152419Sjulian/*
252419Sjulian * netgraph.h
3139823Simp */
4139823Simp
5139823Simp/*-
652419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc.
752419Sjulian * All rights reserved.
852419Sjulian *
952419Sjulian * Subject to the following obligations and disclaimer of warranty, use and
1052419Sjulian * redistribution of this software, in source or object code forms, with or
1152419Sjulian * without modifications are expressly permitted by Whistle Communications;
1252419Sjulian * provided, however, that:
1352419Sjulian * 1. Any and all reproductions of the source or object code must include the
1452419Sjulian *    copyright notice above and the following disclaimer of warranties; and
1552419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle
1652419Sjulian *    Communications, Inc. trademarks, including the mark "WHISTLE
1752419Sjulian *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1852419Sjulian *    such appears in the above copyright notice or in the software.
1952419Sjulian *
2052419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2152419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2252419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2352419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2452419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2552419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2652419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2752419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2852419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2952419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
3052419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3152419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3252419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3352419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3452419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3552419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3652419Sjulian * OF SUCH DAMAGE.
3752419Sjulian *
3867506Sjulian * Author: Julian Elischer <julian@freebsd.org>
3952419Sjulian *
4052419Sjulian * $FreeBSD: releng/10.3/sys/netgraph/netgraph.h 231831 2012-02-16 19:10:01Z glebius $
4152752Sjulian * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $
4252419Sjulian */
4352419Sjulian
4452419Sjulian#ifndef _NETGRAPH_NETGRAPH_H_
45122481Sru#define _NETGRAPH_NETGRAPH_H_
4652419Sjulian
4755205Speter#ifndef _KERNEL
4852419Sjulian#error "This file should not be included in user level programs"
4952419Sjulian#endif
5052419Sjulian
5170784Sjulian#include <sys/queue.h>
5274914Sjhb#include <sys/lock.h>
5370784Sjulian#include <sys/malloc.h>
5470784Sjulian#include <sys/module.h>
5570700Sjulian#include <sys/mutex.h>
56223754Sglebius#include <sys/refcount.h>
57146259Sglebius
58179973Sgnn#ifdef HAVE_KERNEL_OPTION_HEADERS
59146259Sglebius#include "opt_netgraph.h"
60226829Sglebius#include "opt_kdb.h"
61179973Sgnn#endif
62146259Sglebius
6370870Sjulian/* debugging options */
6470870Sjulian#define NG_SEPARATE_MALLOC	/* make modules use their own malloc types */
6570784Sjulian
6670784Sjulian/*
6770784Sjulian * This defines the in-kernel binary interface version.
6870784Sjulian * It is possible to change this but leave the external message
6970784Sjulian * API the same. Each type also has it's own cookies for versioning as well.
7070784Sjulian * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug
7170784Sjulian * modules.
7270784Sjulian */
73178228Smav#define _NG_ABI_VERSION 12
7470784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
7570784Sjulian#define NG_ABI_VERSION	(_NG_ABI_VERSION + 0x10000)
7670784Sjulian#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
7770784Sjulian#define NG_ABI_VERSION	_NG_ABI_VERSION
7870784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
7970784Sjulian
8070784Sjulian
8170784Sjulian/*
8270784Sjulian * Forward references for the basic structures so we can
8370784Sjulian * define the typedefs and use them in the structures themselves.
8470784Sjulian */
8570784Sjulianstruct ng_hook ;
8670784Sjulianstruct ng_node ;
8770784Sjulianstruct ng_item ;
8870700Sjuliantypedef	struct ng_item *item_p;
8970784Sjuliantypedef struct ng_node *node_p;
9070784Sjuliantypedef struct ng_hook *hook_p;
9170700Sjulian
9271885Sjulian/* node method definitions */
9371885Sjuliantypedef	int	ng_constructor_t(node_p node);
94129836Sjuliantypedef	int	ng_close_t(node_p node);
9571885Sjuliantypedef	int	ng_shutdown_t(node_p node);
9671885Sjuliantypedef	int	ng_newhook_t(node_p node, hook_p hook, const char *name);
9771885Sjuliantypedef	hook_p	ng_findhook_t(node_p node, const char *name);
9871885Sjuliantypedef	int	ng_connect_t(hook_p hook);
9971885Sjuliantypedef	int	ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
10071885Sjuliantypedef	int	ng_rcvdata_t(hook_p hook, item_p item);
10171885Sjuliantypedef	int	ng_disconnect_t(hook_p hook);
10271885Sjuliantypedef	int	ng_rcvitem (node_p node, hook_p hook, item_p item);
10371885Sjulian
10470784Sjulian/***********************************************************************
10570784Sjulian ***************** Hook Structure and Methods **************************
10670784Sjulian ***********************************************************************
10770784Sjulian *
10852419Sjulian * Structure of a hook
10952419Sjulian */
11052419Sjulianstruct ng_hook {
111125021Sharti	char	hk_name[NG_HOOKSIZ];	/* what this node knows this link as */
11270784Sjulian	void   *hk_private;		/* node dependant ID for this hook */
11370784Sjulian	int	hk_flags;		/* info about this hook/link */
114148238Sglebius	int	hk_type;		/* tbd: hook data link type */
11570784Sjulian	struct	ng_hook *hk_peer;	/* the other end of this link */
11670784Sjulian	struct	ng_node *hk_node;	/* The node this hook is attached to */
11770784Sjulian	LIST_ENTRY(ng_hook) hk_hooks;	/* linked list of all hooks on node */
11871885Sjulian	ng_rcvmsg_t	*hk_rcvmsg;	/* control messages come here */
11971885Sjulian	ng_rcvdata_t	*hk_rcvdata;	/* data comes here */
120178228Smav	int	hk_refs;		/* dont actually free this till 0 */
12170784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
12270784Sjulian#define HK_MAGIC 0x78573011
12370784Sjulian	int	hk_magic;
12470784Sjulian	char	*lastfile;
12570784Sjulian	int	lastline;
12670784Sjulian	SLIST_ENTRY(ng_hook)	  hk_all;		/* all existing items */
12770784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
12852419Sjulian};
12952419Sjulian/* Flags for a hook */
13052419Sjulian#define HK_INVALID		0x0001	/* don't trust it! */
13169922Sjulian#define HK_QUEUE		0x0002	/* queue for later delivery */
13270700Sjulian#define HK_FORCE_WRITER		0x0004	/* Incoming data queued as a writer */
13370935Sjulian#define HK_DEAD			0x0008	/* This is the dead hook.. don't free */
134175847Smav#define HK_HI_STACK		0x0010	/* Hook has hi stack usage */
135194012Szec#define HK_TO_INBOUND		0x0020	/* Hook on ntw. stack inbound path. */
13652419Sjulian
13752419Sjulian/*
13870784Sjulian * Public Methods for hook
13970784Sjulian * If you can't do it with these you probably shouldn;t be doing it.
14070784Sjulian */
14170784Sjulianvoid ng_unref_hook(hook_p hook); /* don't move this */
142223754Sglebius#define	_NG_HOOK_REF(hook)	refcount_acquire(&(hook)->hk_refs)
14370784Sjulian#define _NG_HOOK_NAME(hook)	((hook)->hk_name)
14470784Sjulian#define _NG_HOOK_UNREF(hook)	ng_unref_hook(hook)
14570784Sjulian#define	_NG_HOOK_SET_PRIVATE(hook, val)	do {(hook)->hk_private = val;} while (0)
14671885Sjulian#define	_NG_HOOK_SET_RCVMSG(hook, val)	do {(hook)->hk_rcvmsg = val;} while (0)
14771885Sjulian#define	_NG_HOOK_SET_RCVDATA(hook, val)	do {(hook)->hk_rcvdata = val;} while (0)
14870784Sjulian#define	_NG_HOOK_PRIVATE(hook)	((hook)->hk_private)
14970784Sjulian#define _NG_HOOK_NOT_VALID(hook)	((hook)->hk_flags & HK_INVALID)
15073370Sjulian#define _NG_HOOK_IS_VALID(hook)	(!((hook)->hk_flags & HK_INVALID))
15170784Sjulian#define _NG_HOOK_NODE(hook)	((hook)->hk_node) /* only rvalue! */
15270784Sjulian#define _NG_HOOK_PEER(hook)	((hook)->hk_peer) /* only rvalue! */
15370784Sjulian#define _NG_HOOK_FORCE_WRITER(hook)				\
15470784Sjulian		do { hook->hk_flags |= HK_FORCE_WRITER; } while (0)
15570784Sjulian#define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0)
156194012Szec#define _NG_HOOK_SET_TO_INBOUND(hook)				\
157194012Szec		do { hook->hk_flags |= HK_TO_INBOUND; } while (0)
158175847Smav#define _NG_HOOK_HI_STACK(hook) do { hook->hk_flags |= HK_HI_STACK; } while (0)
15970784Sjulian
16070784Sjulian/* Some shortcuts */
16170784Sjulian#define NG_PEER_NODE(hook)	NG_HOOK_NODE(NG_HOOK_PEER(hook))
16270784Sjulian#define NG_PEER_HOOK_NAME(hook)	NG_HOOK_NAME(NG_HOOK_PEER(hook))
16370784Sjulian#define NG_PEER_NODE_NAME(hook)	NG_NODE_NAME(NG_PEER_NODE(hook))
16470784Sjulian
16570784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
16670784Sjulian#define _NN_ __FILE__,__LINE__
16770784Sjulianvoid	dumphook (hook_p hook, char *file, int line);
16870784Sjulianstatic __inline void	_chkhook(hook_p hook, char *file, int line);
16970784Sjulianstatic __inline void	_ng_hook_ref(hook_p hook, char * file, int line);
17070784Sjulianstatic __inline char *	_ng_hook_name(hook_p hook, char * file, int line);
17170784Sjulianstatic __inline void	_ng_hook_unref(hook_p hook, char * file, int line);
17270784Sjulianstatic __inline void	_ng_hook_set_private(hook_p hook,
17371885Sjulian				void * val, char * file, int line);
17471885Sjulianstatic __inline void	_ng_hook_set_rcvmsg(hook_p hook,
17571885Sjulian				ng_rcvmsg_t *val, char * file, int line);
17671885Sjulianstatic __inline void	_ng_hook_set_rcvdata(hook_p hook,
17771885Sjulian				ng_rcvdata_t *val, char * file, int line);
17870784Sjulianstatic __inline void *	_ng_hook_private(hook_p hook, char * file, int line);
17970784Sjulianstatic __inline int	_ng_hook_not_valid(hook_p hook, char * file, int line);
18070784Sjulianstatic __inline int	_ng_hook_is_valid(hook_p hook, char * file, int line);
18170784Sjulianstatic __inline node_p	_ng_hook_node(hook_p hook, char * file, int line);
18270784Sjulianstatic __inline hook_p	_ng_hook_peer(hook_p hook, char * file, int line);
18370784Sjulianstatic __inline void	_ng_hook_force_writer(hook_p hook, char * file,
184194012Szec				int line);
185194012Szecstatic __inline void	_ng_hook_force_queue(hook_p hook, char * file,
186194012Szec				int line);
187194012Szecstatic __inline void	_ng_hook_set_to_inbound(hook_p hook, char * file,
188194012Szec				int line);
18970784Sjulian
190148870Sjulianstatic __inline void
19170784Sjulian_chkhook(hook_p hook, char *file, int line)
19270784Sjulian{
19370784Sjulian	if (hook->hk_magic != HK_MAGIC) {
194226829Sglebius		printf("Accessing freed ");
19570784Sjulian		dumphook(hook, file, line);
19670784Sjulian	}
19770784Sjulian	hook->lastline = line;
19870784Sjulian	hook->lastfile = file;
19970784Sjulian}
20070784Sjulian
20170784Sjulianstatic __inline void
20270784Sjulian_ng_hook_ref(hook_p hook, char * file, int line)
20370784Sjulian{
20470784Sjulian	_chkhook(hook, file, line);
20570784Sjulian	_NG_HOOK_REF(hook);
206152451Sglebius}
20770784Sjulian
20870784Sjulianstatic __inline char *
20970784Sjulian_ng_hook_name(hook_p hook, char * file, int line)
21070784Sjulian{
21170784Sjulian	_chkhook(hook, file, line);
21270784Sjulian	return (_NG_HOOK_NAME(hook));
213152451Sglebius}
21470784Sjulian
21570784Sjulianstatic __inline void
21670784Sjulian_ng_hook_unref(hook_p hook, char * file, int line)
21770784Sjulian{
21870784Sjulian	_chkhook(hook, file, line);
21970784Sjulian	_NG_HOOK_UNREF(hook);
220152451Sglebius}
22170784Sjulian
22270784Sjulianstatic __inline void
22370784Sjulian_ng_hook_set_private(hook_p hook, void *val, char * file, int line)
22470784Sjulian{
22570784Sjulian	_chkhook(hook, file, line);
22670784Sjulian	_NG_HOOK_SET_PRIVATE(hook, val);
227152451Sglebius}
22870784Sjulian
22971885Sjulianstatic __inline void
23071885Sjulian_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line)
23171885Sjulian{
23271885Sjulian	_chkhook(hook, file, line);
23371885Sjulian	_NG_HOOK_SET_RCVMSG(hook, val);
234152451Sglebius}
23571885Sjulian
23671885Sjulianstatic __inline void
23771885Sjulian_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line)
23871885Sjulian{
23971885Sjulian	_chkhook(hook, file, line);
24071885Sjulian	_NG_HOOK_SET_RCVDATA(hook, val);
241152451Sglebius}
24271885Sjulian
24370784Sjulianstatic __inline void *
24470784Sjulian_ng_hook_private(hook_p hook, char * file, int line)
24570784Sjulian{
24670784Sjulian	_chkhook(hook, file, line);
24770784Sjulian	return (_NG_HOOK_PRIVATE(hook));
248152451Sglebius}
24970784Sjulian
25070784Sjulianstatic __inline int
25170784Sjulian_ng_hook_not_valid(hook_p hook, char * file, int line)
25270784Sjulian{
25370784Sjulian	_chkhook(hook, file, line);
25470784Sjulian	return (_NG_HOOK_NOT_VALID(hook));
255152451Sglebius}
25670784Sjulian
25770784Sjulianstatic __inline int
25870784Sjulian_ng_hook_is_valid(hook_p hook, char * file, int line)
25970784Sjulian{
26070784Sjulian	_chkhook(hook, file, line);
26170784Sjulian	return (_NG_HOOK_IS_VALID(hook));
262152451Sglebius}
26370784Sjulian
26470784Sjulianstatic __inline node_p
26570784Sjulian_ng_hook_node(hook_p hook, char * file, int line)
26670784Sjulian{
26770784Sjulian	_chkhook(hook, file, line);
26870784Sjulian	return (_NG_HOOK_NODE(hook));
269152451Sglebius}
27070784Sjulian
27170784Sjulianstatic __inline hook_p
27270784Sjulian_ng_hook_peer(hook_p hook, char * file, int line)
27370784Sjulian{
27470784Sjulian	_chkhook(hook, file, line);
27570784Sjulian	return (_NG_HOOK_PEER(hook));
276152451Sglebius}
27770784Sjulian
27870784Sjulianstatic __inline void
27970784Sjulian_ng_hook_force_writer(hook_p hook, char * file, int line)
28070784Sjulian{
28170784Sjulian	_chkhook(hook, file, line);
28270784Sjulian	_NG_HOOK_FORCE_WRITER(hook);
283152451Sglebius}
28470784Sjulian
28570784Sjulianstatic __inline void
28670784Sjulian_ng_hook_force_queue(hook_p hook, char * file, int line)
28770784Sjulian{
28870784Sjulian	_chkhook(hook, file, line);
28970784Sjulian	_NG_HOOK_FORCE_QUEUE(hook);
290152451Sglebius}
29170784Sjulian
292175847Smavstatic __inline void
293194012Szec_ng_hook_set_to_inbound(hook_p hook, char * file, int line)
294194012Szec{
295194012Szec	_chkhook(hook, file, line);
296194012Szec	_NG_HOOK_SET_TO_INBOUND(hook);
297194012Szec}
298194012Szec
299194012Szecstatic __inline void
300175847Smav_ng_hook_hi_stack(hook_p hook, char * file, int line)
301175847Smav{
302175847Smav	_chkhook(hook, file, line);
303175847Smav	_NG_HOOK_HI_STACK(hook);
304175847Smav}
30570784Sjulian
306175847Smav
30770784Sjulian#define	NG_HOOK_REF(hook)		_ng_hook_ref(hook, _NN_)
30870784Sjulian#define NG_HOOK_NAME(hook)		_ng_hook_name(hook, _NN_)
30970784Sjulian#define NG_HOOK_UNREF(hook)		_ng_hook_unref(hook, _NN_)
31070784Sjulian#define	NG_HOOK_SET_PRIVATE(hook, val)	_ng_hook_set_private(hook, val, _NN_)
31171885Sjulian#define	NG_HOOK_SET_RCVMSG(hook, val)	_ng_hook_set_rcvmsg(hook, val, _NN_)
31271885Sjulian#define	NG_HOOK_SET_RCVDATA(hook, val)	_ng_hook_set_rcvdata(hook, val, _NN_)
31370784Sjulian#define	NG_HOOK_PRIVATE(hook)		_ng_hook_private(hook, _NN_)
31470784Sjulian#define NG_HOOK_NOT_VALID(hook)		_ng_hook_not_valid(hook, _NN_)
31570784Sjulian#define NG_HOOK_IS_VALID(hook)		_ng_hook_is_valid(hook, _NN_)
31670784Sjulian#define NG_HOOK_NODE(hook)		_ng_hook_node(hook, _NN_)
31770784Sjulian#define NG_HOOK_PEER(hook)		_ng_hook_peer(hook, _NN_)
31870784Sjulian#define NG_HOOK_FORCE_WRITER(hook)	_ng_hook_force_writer(hook, _NN_)
31970784Sjulian#define NG_HOOK_FORCE_QUEUE(hook)	_ng_hook_force_queue(hook, _NN_)
320194012Szec#define NG_HOOK_SET_TO_INBOUND(hook)	_ng_hook_set_to_inbound(hook, _NN_)
321175847Smav#define NG_HOOK_HI_STACK(hook)		_ng_hook_hi_stack(hook, _NN_)
32270784Sjulian
32370784Sjulian#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
32470784Sjulian
32570784Sjulian#define	NG_HOOK_REF(hook)		_NG_HOOK_REF(hook)
32670784Sjulian#define NG_HOOK_NAME(hook)		_NG_HOOK_NAME(hook)
32770784Sjulian#define NG_HOOK_UNREF(hook)		_NG_HOOK_UNREF(hook)
32870784Sjulian#define	NG_HOOK_SET_PRIVATE(hook, val)	_NG_HOOK_SET_PRIVATE(hook, val)
32971885Sjulian#define	NG_HOOK_SET_RCVMSG(hook, val)	_NG_HOOK_SET_RCVMSG(hook, val)
33071885Sjulian#define	NG_HOOK_SET_RCVDATA(hook, val)	_NG_HOOK_SET_RCVDATA(hook, val)
33170784Sjulian#define	NG_HOOK_PRIVATE(hook)		_NG_HOOK_PRIVATE(hook)
33270784Sjulian#define NG_HOOK_NOT_VALID(hook)		_NG_HOOK_NOT_VALID(hook)
33370784Sjulian#define NG_HOOK_IS_VALID(hook)		_NG_HOOK_IS_VALID(hook)
33470784Sjulian#define NG_HOOK_NODE(hook)		_NG_HOOK_NODE(hook)
33570784Sjulian#define NG_HOOK_PEER(hook)		_NG_HOOK_PEER(hook)
33670784Sjulian#define NG_HOOK_FORCE_WRITER(hook)	_NG_HOOK_FORCE_WRITER(hook)
33770784Sjulian#define NG_HOOK_FORCE_QUEUE(hook)	_NG_HOOK_FORCE_QUEUE(hook)
338194012Szec#define NG_HOOK_SET_TO_INBOUND(hook)	_NG_HOOK_SET_TO_INBOUND(hook)
339175847Smav#define NG_HOOK_HI_STACK(hook)		_NG_HOOK_HI_STACK(hook)
34070784Sjulian
34170784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
34270784Sjulian
34370784Sjulian/***********************************************************************
34470784Sjulian ***************** Node Structure and Methods **************************
34570784Sjulian ***********************************************************************
34652419Sjulian * Structure of a node
34770784Sjulian * including the eembedded queue structure.
34870784Sjulian *
349152451Sglebius * The structure for queueing Netgraph request items
35070784Sjulian * embedded in the node structure
35152419Sjulian */
35270784Sjulianstruct ng_queue {
353178228Smav	u_int		q_flags;	/* Current r/w/q lock flags */
354178228Smav	u_int		q_flags2;	/* Other queue flags */
355152451Sglebius	struct mtx	q_mtx;
356178228Smav	STAILQ_ENTRY(ng_node)	q_work;	/* nodes with work to do */
357178228Smav	STAILQ_HEAD(, ng_item)	queue;	/* actually items queue */
35870784Sjulian};
35970784Sjulian
36052419Sjulianstruct ng_node {
361125021Sharti	char	nd_name[NG_NODESIZ];	/* optional globally unique name */
36270784Sjulian	struct	ng_type *nd_type;	/* the installed 'type' */
36370784Sjulian	int	nd_flags;		/* see below for bit definitions */
36470784Sjulian	int	nd_numhooks;		/* number of hooks */
36570784Sjulian	void   *nd_private;		/* node type dependant node ID */
36670784Sjulian	ng_ID_t	nd_ID;			/* Unique per node */
36770784Sjulian	LIST_HEAD(hooks, ng_hook) nd_hooks;	/* linked list of node hooks */
368231831Sglebius	LIST_ENTRY(ng_node)	  nd_nodes;	/* name hash collision list */
36970784Sjulian	LIST_ENTRY(ng_node)	  nd_idnodes;	/* ID hash collision list */
37070784Sjulian	struct	ng_queue	  nd_input_queue; /* input queue for locking */
371178228Smav	int	nd_refs;		/* # of references to this node */
372191816Szec	struct	vnet		 *nd_vnet;	/* network stack instance */
37370784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
37470784Sjulian#define ND_MAGIC 0x59264837
37570784Sjulian	int	nd_magic;
37670784Sjulian	char	*lastfile;
37770784Sjulian	int	lastline;
37870784Sjulian	SLIST_ENTRY(ng_node)	  nd_all;	/* all existing nodes */
37970784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
38052419Sjulian};
38152419Sjulian
38252419Sjulian/* Flags for a node */
383132464Sjulian#define NGF_INVALID	0x00000001	/* free when refs go to 0 */
384132464Sjulian#define NG_INVALID	NGF_INVALID	/* compat for old code */
385132464Sjulian#define NGF_FORCE_WRITER	0x00000004	/* Never multithread this node */
386132464Sjulian#define NG_FORCE_WRITER	NGF_FORCE_WRITER /* compat for old code */
387132464Sjulian#define NGF_CLOSING	0x00000008	/* ng_rmnode() at work */
388132464Sjulian#define NG_CLOSING	NGF_CLOSING	/* compat for old code */
389132464Sjulian#define NGF_REALLY_DIE	0x00000010	/* "persistent" node is unloading */
390132464Sjulian#define NG_REALLY_DIE	NGF_REALLY_DIE	/* compat for old code */
391175847Smav#define NGF_HI_STACK	0x00000020	/* node has hi stack usage */
39252419Sjulian#define NGF_TYPE1	0x10000000	/* reserved for type specific storage */
39352419Sjulian#define NGF_TYPE2	0x20000000	/* reserved for type specific storage */
39452419Sjulian#define NGF_TYPE3	0x40000000	/* reserved for type specific storage */
39552419Sjulian#define NGF_TYPE4	0x80000000	/* reserved for type specific storage */
39652419Sjulian
39752419Sjulian/*
39870784Sjulian * Public methods for nodes.
39970784Sjulian * If you can't do it with these you probably shouldn't be doing it.
40070784Sjulian */
401223754Sglebiusvoid	ng_unref_node(node_p node); /* don't move this */
40270784Sjulian#define _NG_NODE_NAME(node)	((node)->nd_name + 0)
40370784Sjulian#define _NG_NODE_HAS_NAME(node)	((node)->nd_name[0] + 0)
40470784Sjulian#define _NG_NODE_ID(node)	((node)->nd_ID + 0)
405223754Sglebius#define	_NG_NODE_REF(node)	refcount_acquire(&(node)->nd_refs)
40670784Sjulian#define	_NG_NODE_UNREF(node)	ng_unref_node(node)
40770784Sjulian#define	_NG_NODE_SET_PRIVATE(node, val)	do {(node)->nd_private = val;} while (0)
40870784Sjulian#define	_NG_NODE_PRIVATE(node)	((node)->nd_private)
409132464Sjulian#define _NG_NODE_IS_VALID(node)	(!((node)->nd_flags & NGF_INVALID))
410132464Sjulian#define _NG_NODE_NOT_VALID(node)	((node)->nd_flags & NGF_INVALID)
41170784Sjulian#define _NG_NODE_NUMHOOKS(node)	((node)->nd_numhooks + 0) /* rvalue */
41270784Sjulian#define _NG_NODE_FORCE_WRITER(node)					\
413132464Sjulian	do{ node->nd_flags |= NGF_FORCE_WRITER; }while (0)
414175847Smav#define _NG_NODE_HI_STACK(node)						\
415175847Smav	do{ node->nd_flags |= NGF_HI_STACK; }while (0)
41671849Sjulian#define _NG_NODE_REALLY_DIE(node)					\
417132464Sjulian	do{ node->nd_flags |= (NGF_REALLY_DIE|NGF_INVALID); }while (0)
418132464Sjulian#define _NG_NODE_REVIVE(node) \
419132464Sjulian	do { node->nd_flags &= ~NGF_INVALID; } while (0)
42070784Sjulian/*
42170784Sjulian * The hook iterator.
42270784Sjulian * This macro will call a function of type ng_fn_eachhook for each
42370784Sjulian * hook attached to the node. If the function returns 0, then the
42470784Sjulian * iterator will stop and return a pointer to the hook that returned 0.
42570784Sjulian */
42670784Sjuliantypedef	int	ng_fn_eachhook(hook_p hook, void* arg);
42770784Sjulian#define _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			\
42870784Sjulian	do {								\
429102190Sarchie		hook_p _hook;						\
430102190Sarchie		(rethook) = NULL;					\
431102190Sarchie		LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) {	\
432102190Sarchie			if ((fn)(_hook, arg) == 0) {			\
433102190Sarchie				(rethook) = _hook;			\
43470784Sjulian				break;					\
43570784Sjulian			}						\
43670784Sjulian		}							\
43770784Sjulian	} while (0)
43870784Sjulian
43970784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
44070784Sjulianvoid	dumpnode(node_p node, char *file, int line);
441148870Sjulianstatic __inline void _chknode(node_p node, char *file, int line);
44270784Sjulianstatic __inline char * _ng_node_name(node_p node, char *file, int line);
44370784Sjulianstatic __inline int _ng_node_has_name(node_p node, char *file, int line);
44470784Sjulianstatic __inline ng_ID_t _ng_node_id(node_p node, char *file, int line);
44570784Sjulianstatic __inline void _ng_node_ref(node_p node, char *file, int line);
446223768Sglebiusstatic __inline void _ng_node_unref(node_p node, char *file, int line);
44770784Sjulianstatic __inline void _ng_node_set_private(node_p node, void * val,
44870784Sjulian							char *file, int line);
44970784Sjulianstatic __inline void * _ng_node_private(node_p node, char *file, int line);
45070784Sjulianstatic __inline int _ng_node_is_valid(node_p node, char *file, int line);
45170784Sjulianstatic __inline int _ng_node_not_valid(node_p node, char *file, int line);
45270784Sjulianstatic __inline int _ng_node_numhooks(node_p node, char *file, int line);
45370784Sjulianstatic __inline void _ng_node_force_writer(node_p node, char *file, int line);
45470784Sjulianstatic __inline hook_p _ng_node_foreach_hook(node_p node,
45570784Sjulian			ng_fn_eachhook *fn, void *arg, char *file, int line);
456132464Sjulianstatic __inline void _ng_node_revive(node_p node, char *file, int line);
45770784Sjulian
458152451Sglebiusstatic __inline void
45970784Sjulian_chknode(node_p node, char *file, int line)
46070784Sjulian{
46170784Sjulian	if (node->nd_magic != ND_MAGIC) {
462226829Sglebius		printf("Accessing freed ");
46370784Sjulian		dumpnode(node, file, line);
46470784Sjulian	}
46570784Sjulian	node->lastline = line;
46670784Sjulian	node->lastfile = file;
46770784Sjulian}
46870784Sjulian
46970784Sjulianstatic __inline char *
47070784Sjulian_ng_node_name(node_p node, char *file, int line)
47170784Sjulian{
47270784Sjulian	_chknode(node, file, line);
47370784Sjulian	return(_NG_NODE_NAME(node));
47470784Sjulian}
47570784Sjulian
476152451Sglebiusstatic __inline int
47770784Sjulian_ng_node_has_name(node_p node, char *file, int line)
47870784Sjulian{
47970784Sjulian	_chknode(node, file, line);
48070784Sjulian	return(_NG_NODE_HAS_NAME(node));
48170784Sjulian}
48270784Sjulian
48370784Sjulianstatic __inline ng_ID_t
48470784Sjulian_ng_node_id(node_p node, char *file, int line)
48570784Sjulian{
48670784Sjulian	_chknode(node, file, line);
48770784Sjulian	return(_NG_NODE_ID(node));
48870784Sjulian}
48970784Sjulian
490152451Sglebiusstatic __inline void
49170784Sjulian_ng_node_ref(node_p node, char *file, int line)
49270784Sjulian{
49370784Sjulian	_chknode(node, file, line);
494154270Sglebius	_NG_NODE_REF(node);
49570784Sjulian}
49670784Sjulian
497223761Sglebiusstatic __inline void
49870784Sjulian_ng_node_unref(node_p node, char *file, int line)
49970784Sjulian{
50070784Sjulian	_chknode(node, file, line);
501223761Sglebius	_NG_NODE_UNREF(node);
50270784Sjulian}
50370784Sjulian
50470784Sjulianstatic __inline void
50570784Sjulian_ng_node_set_private(node_p node, void * val, char *file, int line)
50670784Sjulian{
50770784Sjulian	_chknode(node, file, line);
50870784Sjulian	_NG_NODE_SET_PRIVATE(node, val);
50970784Sjulian}
51070784Sjulian
51170784Sjulianstatic __inline void *
51270784Sjulian_ng_node_private(node_p node, char *file, int line)
51370784Sjulian{
51470784Sjulian	_chknode(node, file, line);
51570784Sjulian	return (_NG_NODE_PRIVATE(node));
51670784Sjulian}
51770784Sjulian
51870784Sjulianstatic __inline int
51970784Sjulian_ng_node_is_valid(node_p node, char *file, int line)
52070784Sjulian{
52170784Sjulian	_chknode(node, file, line);
52270784Sjulian	return(_NG_NODE_IS_VALID(node));
52370784Sjulian}
52470784Sjulian
52570784Sjulianstatic __inline int
52670784Sjulian_ng_node_not_valid(node_p node, char *file, int line)
52770784Sjulian{
52870784Sjulian	_chknode(node, file, line);
52970784Sjulian	return(_NG_NODE_NOT_VALID(node));
53070784Sjulian}
53170784Sjulian
53270784Sjulianstatic __inline int
53370784Sjulian_ng_node_numhooks(node_p node, char *file, int line)
53470784Sjulian{
53570784Sjulian	_chknode(node, file, line);
53670784Sjulian	return(_NG_NODE_NUMHOOKS(node));
53770784Sjulian}
53870784Sjulian
53970784Sjulianstatic __inline void
54070784Sjulian_ng_node_force_writer(node_p node, char *file, int line)
54170784Sjulian{
54270784Sjulian	_chknode(node, file, line);
54370784Sjulian	_NG_NODE_FORCE_WRITER(node);
54470784Sjulian}
54570784Sjulian
54671849Sjulianstatic __inline void
547175847Smav_ng_node_hi_stack(node_p node, char *file, int line)
548175847Smav{
549175847Smav	_chknode(node, file, line);
550175847Smav	_NG_NODE_HI_STACK(node);
551175847Smav}
552175847Smav
553175847Smavstatic __inline void
55471849Sjulian_ng_node_really_die(node_p node, char *file, int line)
55571849Sjulian{
55671849Sjulian	_chknode(node, file, line);
55771849Sjulian	_NG_NODE_REALLY_DIE(node);
55871849Sjulian}
55971849Sjulian
560132464Sjulianstatic __inline void
561132464Sjulian_ng_node_revive(node_p node, char *file, int line)
562132464Sjulian{
563132464Sjulian	_chknode(node, file, line);
564132464Sjulian	_NG_NODE_REVIVE(node);
565132464Sjulian}
566132464Sjulian
56770784Sjulianstatic __inline hook_p
56870784Sjulian_ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg,
56970784Sjulian						char *file, int line)
57070784Sjulian{
57170784Sjulian	hook_p hook;
57270784Sjulian	_chknode(node, file, line);
57370784Sjulian	_NG_NODE_FOREACH_HOOK(node, fn, arg, hook);
57470784Sjulian	return (hook);
57570784Sjulian}
57670784Sjulian
57770784Sjulian#define NG_NODE_NAME(node)		_ng_node_name(node, _NN_)
57870784Sjulian#define NG_NODE_HAS_NAME(node)		_ng_node_has_name(node, _NN_)
57970917Sarchie#define NG_NODE_ID(node)		_ng_node_id(node, _NN_)
58070784Sjulian#define NG_NODE_REF(node)		_ng_node_ref(node, _NN_)
58170784Sjulian#define	NG_NODE_UNREF(node)		_ng_node_unref(node, _NN_)
58270784Sjulian#define	NG_NODE_SET_PRIVATE(node, val)	_ng_node_set_private(node, val, _NN_)
58370784Sjulian#define	NG_NODE_PRIVATE(node)		_ng_node_private(node, _NN_)
58470784Sjulian#define NG_NODE_IS_VALID(node)		_ng_node_is_valid(node, _NN_)
58570784Sjulian#define NG_NODE_NOT_VALID(node)		_ng_node_not_valid(node, _NN_)
58670784Sjulian#define NG_NODE_FORCE_WRITER(node) 	_ng_node_force_writer(node, _NN_)
587175847Smav#define NG_NODE_HI_STACK(node) 		_ng_node_hi_stack(node, _NN_)
58871849Sjulian#define NG_NODE_REALLY_DIE(node) 	_ng_node_really_die(node, _NN_)
58970784Sjulian#define NG_NODE_NUMHOOKS(node)		_ng_node_numhooks(node, _NN_)
590132464Sjulian#define NG_NODE_REVIVE(node)		_ng_node_revive(node, _NN_)
59170784Sjulian#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			      \
59270784Sjulian	do {								      \
59370784Sjulian		rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \
59470784Sjulian	} while (0)
59570784Sjulian
59670784Sjulian#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
59770784Sjulian
59870784Sjulian#define NG_NODE_NAME(node)		_NG_NODE_NAME(node)
59970784Sjulian#define NG_NODE_HAS_NAME(node)		_NG_NODE_HAS_NAME(node)
60070784Sjulian#define NG_NODE_ID(node)		_NG_NODE_ID(node)
60170784Sjulian#define	NG_NODE_REF(node)		_NG_NODE_REF(node)
60270784Sjulian#define	NG_NODE_UNREF(node)		_NG_NODE_UNREF(node)
60370784Sjulian#define	NG_NODE_SET_PRIVATE(node, val)	_NG_NODE_SET_PRIVATE(node, val)
60470784Sjulian#define	NG_NODE_PRIVATE(node)		_NG_NODE_PRIVATE(node)
60570784Sjulian#define NG_NODE_IS_VALID(node)		_NG_NODE_IS_VALID(node)
60670784Sjulian#define NG_NODE_NOT_VALID(node)		_NG_NODE_NOT_VALID(node)
60770784Sjulian#define NG_NODE_FORCE_WRITER(node) 	_NG_NODE_FORCE_WRITER(node)
608175847Smav#define NG_NODE_HI_STACK(node) 		_NG_NODE_HI_STACK(node)
60971849Sjulian#define NG_NODE_REALLY_DIE(node) 	_NG_NODE_REALLY_DIE(node)
61070784Sjulian#define NG_NODE_NUMHOOKS(node)		_NG_NODE_NUMHOOKS(node)
611132464Sjulian#define NG_NODE_REVIVE(node)		_NG_NODE_REVIVE(node)
61270784Sjulian#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			\
61370784Sjulian		_NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)
61470784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
61570784Sjulian
61670784Sjulian/***********************************************************************
61770784Sjulian ************* Node Queue and Item Structures and Methods **************
61870784Sjulian ***********************************************************************
61970784Sjulian *
62053913Sarchie */
62171849Sjuliantypedef	void	ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2);
622172806Smavtypedef	int	ng_item_fn2(node_p node, struct ng_item *item, hook_p hook);
623147774Sglebiustypedef	void	ng_apply_t(void *context, int error);
624172806Smavstruct ng_apply_info {
625172806Smav	ng_apply_t	*apply;
626172806Smav	void		*context;
627172806Smav	int		refs;
628177071Smav	int		error;
629172806Smav};
63070700Sjulianstruct ng_item {
63170700Sjulian	u_long	el_flags;
632178228Smav	STAILQ_ENTRY(ng_item)	el_next;
63370700Sjulian	node_p	el_dest; /* The node it will be applied against (or NULL) */
63470700Sjulian	hook_p	el_hook; /* Entering hook. Optional in Control messages */
63570700Sjulian	union {
636131374Sjulian		struct mbuf	*da_m;
63770700Sjulian		struct {
63870700Sjulian			struct ng_mesg	*msg_msg;
63970700Sjulian			ng_ID_t		msg_retaddr;
64070700Sjulian		} msg;
64171047Sjulian		struct {
642172806Smav			union {
643172806Smav				ng_item_fn	*fn_fn;
644172806Smav				ng_item_fn2	*fn_fn2;
645172806Smav			} fn_fn;
64671047Sjulian			void 		*fn_arg1;
64771047Sjulian			int		fn_arg2;
64871047Sjulian		} fn;
64970700Sjulian	} body;
650147774Sglebius	/*
651147774Sglebius	 * Optional callback called when item is being applied,
652147774Sglebius	 * and its context.
653147774Sglebius	 */
654172806Smav	struct ng_apply_info	*apply;
655178228Smav	u_int	depth;
65670784Sjulian#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
65770700Sjulian	char *lastfile;
65870700Sjulian	int  lastline;
65970700Sjulian	TAILQ_ENTRY(ng_item)	  all;		/* all existing items */
66070784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
66170700Sjulian};
66271047Sjulian
66371047Sjulian#define NGQF_TYPE	0x03		/* MASK of content definition */
66471047Sjulian#define NGQF_MESG	0x00		/* the queue element is a message */
66570700Sjulian#define NGQF_DATA	0x01		/* the queue element is data */
66671047Sjulian#define NGQF_FN		0x02		/* the queue element is a function */
667172806Smav#define NGQF_FN2	0x03		/* the queue element is a new function */
66871047Sjulian
669151973Sglebius#define NGQF_RW		0x04		/* MASK for wanted queue mode */
670151973Sglebius#define NGQF_READER	0x04		/* wants to be a reader */
671151973Sglebius#define NGQF_WRITER	0x00		/* wants to be a writer */
67270700Sjulian
673151973Sglebius#define NGQF_QMODE	0x08		/* MASK for how it was queued */
674151973Sglebius#define NGQF_QREADER	0x08		/* was queued as a reader */
675151973Sglebius#define NGQF_QWRITER	0x00		/* was queued as a writer */
676151973Sglebius
67770159Sjulian/*
67870700Sjulian * Get the mbuf (etc) out of an item.
67970700Sjulian * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM()
68070700Sjulian * with it, (to avoid freeing the things twice).
68170700Sjulian * If you don't want to zero out the item then realise that the
68270700Sjulian * item still owns it.
68370700Sjulian * Retaddr is different. There are no references on that. It's just a number.
68470700Sjulian * The debug versions must be either all used everywhere or not at all.
68570700Sjulian */
68670700Sjulian
687131374Sjulian#define _NGI_M(i) ((i)->body.da_m)
68870700Sjulian#define _NGI_MSG(i) ((i)->body.msg.msg_msg)
68970700Sjulian#define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr)
690172806Smav#define	_NGI_FN(i) ((i)->body.fn.fn_fn.fn_fn)
691172806Smav#define	_NGI_FN2(i) ((i)->body.fn.fn_fn.fn_fn2)
69271047Sjulian#define	_NGI_ARG1(i) ((i)->body.fn.fn_arg1)
69371047Sjulian#define	_NGI_ARG2(i) ((i)->body.fn.fn_arg2)
69471849Sjulian#define	_NGI_NODE(i) ((i)->el_dest)
69571849Sjulian#define	_NGI_HOOK(i) ((i)->el_hook)
69671849Sjulian#define	_NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0)
69771849Sjulian#define	_NGI_CLR_HOOK(i)   do {						\
698102190Sarchie		hook_p _hook = _NGI_HOOK(i);				\
699102190Sarchie		if (_hook) {						\
700102190Sarchie			_NG_HOOK_UNREF(_hook);				\
70171849Sjulian			_NGI_HOOK(i) = NULL;				\
70271849Sjulian		}							\
70371849Sjulian	} while (0)
70471849Sjulian#define	_NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0)
70571849Sjulian#define	_NGI_CLR_NODE(i)   do {						\
706102190Sarchie		node_p _node = _NGI_NODE(i);				\
707102190Sarchie		if (_node) {						\
708102190Sarchie			_NG_NODE_UNREF(_node);				\
70971849Sjulian			_NGI_NODE(i) = NULL;				\
71071849Sjulian		}							\
71171849Sjulian	} while (0)
71270700Sjulian
71370784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
71470784Sjulianvoid				dumpitem(item_p item, char *file, int line);
71570784Sjulianstatic __inline void		_ngi_check(item_p item, char *file, int line) ;
71670784Sjulianstatic __inline struct mbuf **	_ngi_m(item_p item, char *file, int line) ;
71771849Sjulianstatic __inline ng_ID_t *	_ngi_retaddr(item_p item, char *file, int line);
71871849Sjulianstatic __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ;
71971849Sjulianstatic __inline ng_item_fn **	_ngi_fn(item_p item, char *file, int line) ;
720172806Smavstatic __inline ng_item_fn2 **	_ngi_fn2(item_p item, char *file, int line) ;
72171849Sjulianstatic __inline void **		_ngi_arg1(item_p item, char *file, int line) ;
72271849Sjulianstatic __inline int *		_ngi_arg2(item_p item, char *file, int line) ;
72371849Sjulianstatic __inline node_p		_ngi_node(item_p item, char *file, int line);
72471849Sjulianstatic __inline hook_p		_ngi_hook(item_p item, char *file, int line);
72570700Sjulian
72670700Sjulianstatic __inline void
727152451Sglebius_ngi_check(item_p item, char *file, int line)
72870700Sjulian{
72970700Sjulian	(item)->lastline = line;
73070700Sjulian	(item)->lastfile = file;
73170700Sjulian}
73270700Sjulian
73370700Sjulianstatic __inline struct mbuf **
734152451Sglebius_ngi_m(item_p item, char *file, int line)
73570700Sjulian{
73670700Sjulian	_ngi_check(item, file, line);
73770700Sjulian	return (&_NGI_M(item));
73870700Sjulian}
73970700Sjulian
74070700Sjulianstatic __inline struct ng_mesg **
741152451Sglebius_ngi_msg(item_p item, char *file, int line)
74270700Sjulian{
74370700Sjulian	_ngi_check(item, file, line);
74470700Sjulian	return (&_NGI_MSG(item));
74570700Sjulian}
74670700Sjulian
74770700Sjulianstatic __inline ng_ID_t *
748152451Sglebius_ngi_retaddr(item_p item, char *file, int line)
74970700Sjulian{
75070700Sjulian	_ngi_check(item, file, line);
75170700Sjulian	return (&_NGI_RETADDR(item));
75270700Sjulian}
75370700Sjulian
75471047Sjulianstatic __inline ng_item_fn **
755152451Sglebius_ngi_fn(item_p item, char *file, int line)
75671047Sjulian{
75771047Sjulian	_ngi_check(item, file, line);
75871047Sjulian	return (&_NGI_FN(item));
75971047Sjulian}
76070700Sjulian
761172806Smavstatic __inline ng_item_fn2 **
762172806Smav_ngi_fn2(item_p item, char *file, int line)
763172806Smav{
764172806Smav	_ngi_check(item, file, line);
765172806Smav	return (&_NGI_FN2(item));
766172806Smav}
767172806Smav
76871047Sjulianstatic __inline void **
769152451Sglebius_ngi_arg1(item_p item, char *file, int line)
77071047Sjulian{
77171047Sjulian	_ngi_check(item, file, line);
77271047Sjulian	return (&_NGI_ARG1(item));
77371047Sjulian}
77470700Sjulian
77571047Sjulianstatic __inline int *
776152451Sglebius_ngi_arg2(item_p item, char *file, int line)
77771047Sjulian{
77871047Sjulian	_ngi_check(item, file, line);
77971047Sjulian	return (&_NGI_ARG2(item));
78071047Sjulian}
78170700Sjulian
78271849Sjulianstatic __inline node_p
78371849Sjulian_ngi_node(item_p item, char *file, int line)
78471849Sjulian{
78571849Sjulian	_ngi_check(item, file, line);
78671849Sjulian	return (_NGI_NODE(item));
78771849Sjulian}
78871849Sjulian
78971849Sjulianstatic __inline hook_p
79071849Sjulian_ngi_hook(item_p item, char *file, int line)
79171849Sjulian{
79271849Sjulian	_ngi_check(item, file, line);
79371849Sjulian	return (_NGI_HOOK(item));
79471849Sjulian}
79571849Sjulian
79671047Sjulian#define NGI_M(i)	(*_ngi_m(i, _NN_))
79771047Sjulian#define NGI_MSG(i)	(*_ngi_msg(i, _NN_))
79871047Sjulian#define NGI_RETADDR(i)	(*_ngi_retaddr(i, _NN_))
79971047Sjulian#define NGI_FN(i)	(*_ngi_fn(i, _NN_))
800172806Smav#define NGI_FN2(i)	(*_ngi_fn2(i, _NN_))
80171047Sjulian#define NGI_ARG1(i)	(*_ngi_arg1(i, _NN_))
80271047Sjulian#define NGI_ARG2(i)	(*_ngi_arg2(i, _NN_))
80371849Sjulian#define NGI_HOOK(i)	_ngi_hook(i, _NN_)
80471849Sjulian#define NGI_NODE(i)	_ngi_node(i, _NN_)
80571849Sjulian#define	NGI_SET_HOOK(i,h)						\
80671849Sjulian	do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0)
80771849Sjulian#define	NGI_CLR_HOOK(i)							\
80871849Sjulian	do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0)
80971849Sjulian#define	NGI_SET_NODE(i,n)						\
81071849Sjulian	do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0)
81171849Sjulian#define	NGI_CLR_NODE(i)							\
81271849Sjulian	do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0)
81370700Sjulian
81470700Sjulian#define NG_FREE_ITEM(item)						\
81570700Sjulian	do {								\
81670784Sjulian		_ngi_check(item, _NN_);					\
81770700Sjulian		ng_free_item((item));					\
81870700Sjulian	} while (0)
81970700Sjulian
82070700Sjulian#define	SAVE_LINE(item)							\
82170700Sjulian	do {								\
82270700Sjulian		(item)->lastline = __LINE__;				\
82370700Sjulian		(item)->lastfile = __FILE__;				\
82470700Sjulian	} while (0)
82570700Sjulian
82670784Sjulian#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
82770700Sjulian
82870700Sjulian#define NGI_M(i)	_NGI_M(i)
82970700Sjulian#define NGI_MSG(i)	_NGI_MSG(i)
83070700Sjulian#define NGI_RETADDR(i)	_NGI_RETADDR(i)
83171047Sjulian#define NGI_FN(i)	_NGI_FN(i)
832172806Smav#define NGI_FN2(i)	_NGI_FN2(i)
83371047Sjulian#define NGI_ARG1(i)	_NGI_ARG1(i)
83471047Sjulian#define NGI_ARG2(i)	_NGI_ARG2(i)
83571849Sjulian#define	NGI_NODE(i)	_NGI_NODE(i)
83671849Sjulian#define	NGI_HOOK(i)	_NGI_HOOK(i)
83771849Sjulian#define	NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h)
83871849Sjulian#define	NGI_CLR_HOOK(i)	  _NGI_CLR_HOOK(i)
83971849Sjulian#define	NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n)
84071849Sjulian#define	NGI_CLR_NODE(i)	  _NGI_CLR_NODE(i)
84170700Sjulian
84270700Sjulian#define	NG_FREE_ITEM(item)	ng_free_item((item))
84370784Sjulian#define	SAVE_LINE(item)		do {} while (0)
84470700Sjulian
84570784Sjulian#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
84671849Sjulian
84771849Sjulian#define NGI_GET_M(i,m)							\
84871849Sjulian	do {								\
84971849Sjulian		(m) = NGI_M(i);						\
85071849Sjulian		_NGI_M(i) = NULL;					\
85171849Sjulian	} while (0)
85271849Sjulian
85371849Sjulian#define NGI_GET_MSG(i,m)						\
85471849Sjulian	do {								\
85571849Sjulian		(m) = NGI_MSG(i);					\
85671849Sjulian		_NGI_MSG(i) = NULL;					\
85771849Sjulian	} while (0)
85871849Sjulian
85971849Sjulian#define NGI_GET_NODE(i,n)	/* YOU NOW HAVE THE REFERENCE */	\
86071849Sjulian	do {								\
86171849Sjulian		(n) = NGI_NODE(i);					\
86271849Sjulian		_NGI_NODE(i) = NULL;					\
86371849Sjulian	} while (0)
86471849Sjulian
86571849Sjulian#define NGI_GET_HOOK(i,h)						\
86671849Sjulian	do {								\
86771849Sjulian		(h) = NGI_HOOK(i);					\
86871849Sjulian		_NGI_HOOK(i) = NULL;					\
86971849Sjulian	} while (0)
87071849Sjulian
871151973Sglebius#define NGI_SET_WRITER(i)	((i)->el_flags &= ~NGQF_QMODE)
872151973Sglebius#define NGI_SET_READER(i)	((i)->el_flags |= NGQF_QREADER)
873151973Sglebius
874151973Sglebius#define NGI_QUEUED_READER(i)	((i)->el_flags & NGQF_QREADER)
875151973Sglebius#define NGI_QUEUED_WRITER(i)	(((i)->el_flags & NGQF_QMODE) == NGQF_QWRITER)
87670700Sjulian
87770700Sjulian/**********************************************************************
87870700Sjulian* Data macros.  Send, manipulate and free.
87970700Sjulian**********************************************************************/
88073371Sjulian/*
88173371Sjulian * Assuming the data is already ok, just set the new address and send
88273371Sjulian */
883154276Sglebius#define NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags)		\
88470700Sjulian	do {								\
88573371Sjulian		(error) =						\
886154276Sglebius		    ng_address_hook(NULL, (item), (hook), NG_NOFLAGS);	\
88773371Sjulian		if (error == 0) {					\
88873371Sjulian			SAVE_LINE(item);				\
889154276Sglebius			(error) = ng_snd_item((item), (flags));		\
89070700Sjulian		}							\
89173371Sjulian		(item) = NULL;						\
89252419Sjulian	} while (0)
893154276Sglebius#define	NG_FWD_ITEM_HOOK(error, item, hook)	\
894154276Sglebius		NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, NG_NOFLAGS)
89552419Sjulian
89670700Sjulian/*
897131374Sjulian * Forward a data packet. Mbuf pointer is updated to new value. We
898131374Sjulian * presume you dealt with the old one when you update it to the new one
899131374Sjulian * (or it maybe the old one). We got a packet and possibly had to modify
900131374Sjulian * the mbuf. You should probably use NGI_GET_M() if you are going to use
901131374Sjulian * this too.
90270700Sjulian */
903154276Sglebius#define NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, flags)		\
90459728Sjulian	do {								\
90573371Sjulian		NGI_M(item) = (m);					\
90673371Sjulian		(m) = NULL;						\
907154276Sglebius		NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags);	\
90873371Sjulian	} while (0)
909154276Sglebius#define	NG_FWD_NEW_DATA(error, item, hook, m)	\
910154276Sglebius		NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, NG_NOFLAGS)
91173371Sjulian
912131374Sjulian/* Send a previously unpackaged mbuf. XXX: This should be called
913131374Sjulian * NG_SEND_DATA in future, but this name is kept for compatibility
914131374Sjulian * reasons.
915131374Sjulian */
916154276Sglebius#define NG_SEND_DATA_FLAGS(error, hook, m, flags)			\
91773371Sjulian	do {								\
918102190Sarchie		item_p _item;						\
919154276Sglebius		if ((_item = ng_package_data((m), flags))) {		\
920154276Sglebius			NG_FWD_ITEM_HOOK_FLAGS(error, _item, hook, flags);\
92173371Sjulian		} else {						\
92273371Sjulian			(error) = ENOMEM;				\
92370700Sjulian		}							\
92469922Sjulian		(m) = NULL;						\
92569922Sjulian	} while (0)
92669922Sjulian
927154276Sglebius#define NG_SEND_DATA_ONLY(error, hook, m)	\
928154276Sglebius		NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS)
929154276Sglebius/* NG_SEND_DATA() compat for meta-data times */
930154276Sglebius#define	NG_SEND_DATA(error, hook, m, x)	\
931154276Sglebius		NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS)
93259728Sjulian
93370700Sjulian#define NG_FREE_MSG(msg)						\
93470700Sjulian	do {								\
93570700Sjulian		if ((msg)) {						\
936184205Sdes			free((msg), M_NETGRAPH_MSG);			\
93770700Sjulian			(msg) = NULL;					\
93870700Sjulian		}	 						\
93970700Sjulian	} while (0)
94070700Sjulian
94170700Sjulian#define NG_FREE_M(m)							\
94252419Sjulian	do {								\
94352419Sjulian		if ((m)) {						\
94452419Sjulian			m_freem((m));					\
94570700Sjulian			(m) = NULL;					\
94652419Sjulian		}							\
94770700Sjulian	} while (0)
94870784Sjulian
94970700Sjulian/*****************************************
95070700Sjulian* Message macros
95170700Sjulian*****************************************/
95252419Sjulian
95370700Sjulian#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)		\
95470700Sjulian	do {								\
955102190Sarchie		item_p _item;						\
956146281Sglebius		if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
95770784Sjulian			(msg) = NULL;					\
95870784Sjulian			(error) = ENOMEM;				\
95970784Sjulian			break;						\
96070784Sjulian		}							\
961102190Sarchie		if (((error) = ng_address_hook((here), (_item),		\
96270784Sjulian					(hook), (retaddr))) == 0) {	\
963102190Sarchie			SAVE_LINE(_item);				\
964102190Sarchie			(error) = ng_snd_item((_item), 0);		\
96570700Sjulian		}							\
96670700Sjulian		(msg) = NULL;						\
96770700Sjulian	} while (0)
96870700Sjulian
96970700Sjulian#define NG_SEND_MSG_PATH(error, here, msg, path, retaddr)		\
97070700Sjulian	do {								\
971102190Sarchie		item_p _item;						\
972146281Sglebius		if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
97370784Sjulian			(msg) = NULL;					\
97470784Sjulian			(error) = ENOMEM;				\
97570784Sjulian			break;						\
97670784Sjulian		}							\
977102190Sarchie		if (((error) = ng_address_path((here), (_item),		\
97870784Sjulian					(path), (retaddr))) == 0) {	\
979102190Sarchie			SAVE_LINE(_item);				\
980102190Sarchie			(error) = ng_snd_item((_item), 0);		\
98170700Sjulian		}							\
98270700Sjulian		(msg) = NULL;						\
98370700Sjulian	} while (0)
98470700Sjulian
98570700Sjulian#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr)			\
98670700Sjulian	do {								\
987102190Sarchie		item_p _item;						\
988146281Sglebius		if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
98970784Sjulian			(msg) = NULL;					\
99070784Sjulian			(error) = ENOMEM;				\
99170784Sjulian			break;						\
99270784Sjulian		}							\
993102190Sarchie		if (((error) = ng_address_ID((here), (_item),		\
99470784Sjulian					(ID), (retaddr))) == 0) {	\
995102190Sarchie			SAVE_LINE(_item);				\
996102190Sarchie			(error) = ng_snd_item((_item), 0);		\
99770700Sjulian		}							\
99870700Sjulian		(msg) = NULL;						\
99970700Sjulian	} while (0)
100070700Sjulian
100152419Sjulian/*
100270700Sjulian * Redirect the message to the next hop using the given hook.
100370700Sjulian * ng_retarget_msg() frees the item if there is an error
100470700Sjulian * and returns an error code.  It returns 0 on success.
100570700Sjulian */
100670700Sjulian#define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr)		\
100770700Sjulian	do {								\
100870784Sjulian		if (((error) = ng_address_hook((here), (item),		\
100970700Sjulian					(hook), (retaddr))) == 0) {	\
101070700Sjulian			SAVE_LINE(item);				\
101170700Sjulian			(error) = ng_snd_item((item), 0);		\
101270700Sjulian		}							\
101370700Sjulian		(item) = NULL;						\
101470700Sjulian	} while (0)
101570700Sjulian
101670700Sjulian/*
101770700Sjulian * Send a queue item back to it's originator with a response message.
101870700Sjulian * Assume original message was removed and freed separatly.
101970700Sjulian */
102070700Sjulian#define NG_RESPOND_MSG(error, here, item, resp)				\
102170700Sjulian	do {								\
102270700Sjulian		if (resp) {						\
1023102190Sarchie			ng_ID_t _dest = NGI_RETADDR(item);		\
1024102244Sarchie			NGI_RETADDR(item) = 0;				\
102570700Sjulian			NGI_MSG(item) = resp;				\
1026163460Sglebius			if ((error = ng_address_ID((here), (item),	\
1027102244Sarchie					_dest, 0)) == 0) {		\
102870700Sjulian				SAVE_LINE(item);			\
1029146305Sglebius				(error) = ng_snd_item((item), NG_QUEUE);\
103070700Sjulian			}						\
1031163460Sglebius		} else							\
103270700Sjulian			NG_FREE_ITEM(item);				\
103370700Sjulian		(item) = NULL;						\
103470700Sjulian	} while (0)
103570700Sjulian
103670700Sjulian
103770784Sjulian/***********************************************************************
103870784Sjulian ******** Structures Definitions and Macros for defining a node  *******
103970784Sjulian ***********************************************************************
1040152451Sglebius *
104170784Sjulian * Here we define the structures needed to actually define a new node
104270784Sjulian * type.
104370784Sjulian */
104470784Sjulian
104570700Sjulian/*
104670784Sjulian * Command list -- each node type specifies the command that it knows
104770784Sjulian * how to convert between ASCII and binary using an array of these.
104870784Sjulian * The last element in the array must be a terminator with cookie=0.
104970784Sjulian */
105070784Sjulian
105170784Sjulianstruct ng_cmdlist {
105270784Sjulian	u_int32_t			cookie;		/* command typecookie */
105370784Sjulian	int				cmd;		/* command number */
105470784Sjulian	const char			*name;		/* command name */
105570784Sjulian	const struct ng_parse_type	*mesgType;	/* args if !NGF_RESP */
105670784Sjulian	const struct ng_parse_type	*respType;	/* args if NGF_RESP */
105770784Sjulian};
105870784Sjulian
105970784Sjulian/*
106070784Sjulian * Structure of a node type
106170784Sjulian * If data is sent to the "rcvdata()" entrypoint then the system
106270784Sjulian * may decide to defer it until later by queing it with the normal netgraph
106370784Sjulian * input queuing system.  This is decidde by the HK_QUEUE flag being set in
106470784Sjulian * the flags word of the peer (receiving) hook. The dequeuing mechanism will
106570784Sjulian * ensure it is not requeued again.
106670784Sjulian * Note the input queueing system is to allow modules
106770784Sjulian * to 'release the stack' or to pass data across spl layers.
106870784Sjulian * The data will be redelivered as soon as the NETISR code runs
106970784Sjulian * which may be almost immediatly.  A node may also do it's own queueing
107070784Sjulian * for other reasons (e.g. device output queuing).
107170784Sjulian */
107270784Sjulianstruct ng_type {
107370784Sjulian
107470784Sjulian	u_int32_t	version; 	/* must equal NG_API_VERSION */
107570784Sjulian	const char	*name;		/* Unique type name */
107670784Sjulian	modeventhand_t	mod_event;	/* Module event handler (optional) */
107770784Sjulian	ng_constructor_t *constructor;	/* Node constructor */
107870784Sjulian	ng_rcvmsg_t	*rcvmsg;	/* control messages come here */
1079129836Sjulian	ng_close_t	*close;		/* warn about forthcoming shutdown */
108070784Sjulian	ng_shutdown_t	*shutdown;	/* reset, and free resources */
108170784Sjulian	ng_newhook_t	*newhook;	/* first notification of new hook */
108270784Sjulian	ng_findhook_t	*findhook;	/* only if you have lots of hooks */
108370784Sjulian	ng_connect_t	*connect;	/* final notification of new hook */
108470784Sjulian	ng_rcvdata_t	*rcvdata;	/* data comes here */
108570784Sjulian	ng_disconnect_t	*disconnect;	/* notify on disconnect */
108670784Sjulian
108770784Sjulian	const struct	ng_cmdlist *cmdlist;	/* commands we can convert */
108870784Sjulian
108970784Sjulian	/* R/W data private to the base netgraph code DON'T TOUCH! */
109070784Sjulian	LIST_ENTRY(ng_type) types;		/* linked list of all types */
109170784Sjulian	int		    refs;		/* number of instances */
109270784Sjulian};
109370784Sjulian
109470784Sjulian/*
109552419Sjulian * Use the NETGRAPH_INIT() macro to link a node type into the
109652419Sjulian * netgraph system. This works for types compiled into the kernel
109752419Sjulian * as well as KLD modules. The first argument should be the type
109852419Sjulian * name (eg, echo) and the second a pointer to the type struct.
109952419Sjulian *
110052419Sjulian * If a different link time is desired, e.g., a device driver that
110152419Sjulian * needs to install its netgraph type before probing, use the
1102148646Sru * NETGRAPH_INIT_ORDERED() macro instead.  Device drivers probably
1103148646Sru * want to use SI_SUB_DRIVERS/SI_ORDER_FIRST.
110452419Sjulian */
110552419Sjulian
110652419Sjulian#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order)	\
110752419Sjulianstatic moduledata_t ng_##typename##_mod = {				\
110852419Sjulian	"ng_" #typename,						\
110952419Sjulian	ng_mod_event,							\
111052419Sjulian	(typestructp)							\
111152419Sjulian};									\
111259756SpeterDECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order);		\
111372053SjulianMODULE_DEPEND(ng_##typename, netgraph,	NG_ABI_VERSION,			\
111472053Sjulian					NG_ABI_VERSION,			\
111572053Sjulian					NG_ABI_VERSION)
111652419Sjulian
111752419Sjulian#define NETGRAPH_INIT(tn, tp)						\
1118195837Srwatson	NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_MIDDLE)
111952419Sjulian
112052419Sjulian/* Special malloc() type for netgraph structs and ctrl messages */
1121152451Sglebius/* Only these two types should be visible to nodes */
112252419SjulianMALLOC_DECLARE(M_NETGRAPH);
112370700SjulianMALLOC_DECLARE(M_NETGRAPH_MSG);
112452419Sjulian
112572946Sjulian/* declare the base of the netgraph sysclt hierarchy */
112672946Sjulian/* but only if this file cares about sysctls */
112772946Sjulian#ifdef	SYSCTL_DECL
112872946SjulianSYSCTL_DECL(_net_graph);
112972946Sjulian#endif
113070700Sjulian
113170784Sjulian/*
113270784Sjulian * Methods that the nodes can use.
1133152451Sglebius * Many of these methods should usually NOT be used directly but via
113470784Sjulian * Macros above.
113570784Sjulian */
113670700Sjulianint	ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr);
113770700Sjulianint	ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
1138227130Sfjoeint	ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr);
1139129836Sjulianint	ng_bypass(hook_p hook1, hook_p hook2);
114054096Sarchiehook_p	ng_findhook(node_p node, const char *name);
1141132705Sglebiusstruct	ng_type *ng_findtype(const char *type);
114252419Sjulianint	ng_make_node_common(struct ng_type *typep, node_p *nodep);
114352419Sjulianint	ng_name_node(node_p node, const char *name);
1144191510Szecnode_p	ng_name2noderef(node_p node, const char *name);
114552419Sjulianint	ng_newtype(struct ng_type *tp);
114652722Sjulianng_ID_t ng_node2ID(node_p node);
1147146281Sglebiusitem_p	ng_package_data(struct mbuf *m, int flags);
1148146281Sglebiusitem_p	ng_package_msg(struct ng_mesg *msg, int flags);
114970700Sjulianitem_p	ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg);
115070700Sjulianvoid	ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr);
115170935Sjulianint	ng_rmhook_self(hook_p hook);	/* if a node wants to kill a hook */
115270935Sjulianint	ng_rmnode_self(node_p here);	/* if a node wants to suicide */
115380222Sjulianint	ng_rmtype(struct ng_type *tp);
115470700Sjulianint	ng_snd_item(item_p item, int queue);
1155173605Sglebiusint 	ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void *arg1,
1156173605Sglebius	int arg2);
1157173605Sglebiusint 	ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void *arg1,
1158173605Sglebius	int arg2, int flags);
1159173605Sglebiusint 	ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn,
1160146281Sglebius	void *arg1, int arg2, int flags);
1161138268Sglebiusint	ng_uncallout(struct callout *c, node_p node);
1162138268Sglebiusint	ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
116391711Sjulian	    ng_item_fn *fn, void * arg1, int arg2);
1164171637Srwatson#define	ng_callout_init(c)	callout_init(c, CALLOUT_MPSAFE)
116552419Sjulian
1166146281Sglebius/* Flags for netgraph functions. */
1167146281Sglebius#define	NG_NOFLAGS	0x00000000	/* no special options */
1168146281Sglebius#define	NG_QUEUE	0x00000001	/* enqueue item, don't dispatch */
1169146281Sglebius#define	NG_WAITOK	0x00000002	/* use M_WAITOK, etc. */
1170173605Sglebius/* XXXGL: NG_PROGRESS unused since ng_base.c rev. 1.136. Should be deleted? */
1171147774Sglebius#define	NG_PROGRESS	0x00000004	/* return EINPROGRESS if queued */
1172173605Sglebius#define	NG_REUSE_ITEM	0x00000008	/* supplied item should be reused */
1173146281Sglebius
117470784Sjulian/*
1175131108Sjulian * prototypes the user should DEFINITELY not use directly
117670784Sjulian */
117770784Sjulianvoid	ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */
117870784Sjulianint	ng_mod_event(module_t mod, int what, void *arg);
117970784Sjulian
1180131108Sjulian/*
1181131108Sjulian * Tag definitions and constants
1182131108Sjulian */
1183131108Sjulian
1184131108Sjulian#define	NG_TAG_PRIO	1
1185131108Sjulian
1186131108Sjulianstruct ng_tag_prio {
1187131108Sjulian	struct m_tag	tag;
1188131108Sjulian	char	priority;
1189131108Sjulian	char	discardability;
1190131108Sjulian};
1191131108Sjulian
1192131108Sjulian#define	NG_PRIO_CUTOFF		32
1193131108Sjulian#define	NG_PRIO_LINKSTATE	64
1194131108Sjulian
1195131374Sjulian/* Macros and declarations to keep compatibility with metadata, which
1196131374Sjulian * is obsoleted now. To be deleted.
1197131374Sjulian */
1198131374Sjuliantypedef void *meta_p;
1199131374Sjulian#define _NGI_META(i)	NULL
1200131374Sjulian#define NGI_META(i)	NULL
1201131374Sjulian#define NG_FREE_META(meta)
1202131374Sjulian#define NGI_GET_META(i,m)
1203131374Sjulian#define	ng_copy_meta(meta) NULL
1204131374Sjulian
1205194012Szec/*
1206194012Szec * Mark the current thread when called from the outbound path of the
1207194012Szec * network stack, in order to enforce queuing on ng nodes calling into
1208194012Szec * the inbound network stack path.
1209194012Szec */
1210194012Szec#define NG_OUTBOUND_THREAD_REF()					\
1211194012Szec	curthread->td_ng_outbound++
1212194012Szec#define NG_OUTBOUND_THREAD_UNREF()					\
1213194012Szec	do {								\
1214194012Szec		curthread->td_ng_outbound--;				\
1215194012Szec		KASSERT(curthread->td_ng_outbound >= 0,			\
1216194012Szec		    ("%s: negative td_ng_outbound", __func__));		\
1217194012Szec	} while (0)
1218194012Szec
121952419Sjulian#endif /* _NETGRAPH_NETGRAPH_H_ */
1220