netgraph.h revision 143385
146409Sjkh/*
246409Sjkh * netgraph.h
346409Sjkh */
446409Sjkh
546409Sjkh/*-
646409Sjkh * Copyright (c) 1996-1999 Whistle Communications, Inc.
746409Sjkh * All rights reserved.
846409Sjkh *
946409Sjkh * Subject to the following obligations and disclaimer of warranty, use and
1046409Sjkh * redistribution of this software, in source or object code forms, with or
1146409Sjkh * without modifications are expressly permitted by Whistle Communications;
1246409Sjkh * provided, however, that:
1346409Sjkh * 1. Any and all reproductions of the source or object code must include the
1446409Sjkh *    copyright notice above and the following disclaimer of warranties; and
1546409Sjkh * 2. No rights are granted, in any manner or form, to use Whistle
1646409Sjkh *    Communications, Inc. trademarks, including the mark "WHISTLE
1746409Sjkh *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1846409Sjkh *    such appears in the above copyright notice or in the software.
1946409Sjkh *
2046409Sjkh * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2146409Sjkh * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2246409Sjkh * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2346409Sjkh * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2446409Sjkh * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2546409Sjkh * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2650477Speter * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2746409Sjkh * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2846407Sjkh * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2946407Sjkh * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
3046899Sdes * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3146407Sjkh * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3246407Sjkh * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3346407Sjkh * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3446407Sjkh * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3546407Sjkh * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3646407Sjkh * OF SUCH DAMAGE.
3746407Sjkh *
3846407Sjkh * Author: Julian Elischer <julian@freebsd.org>
3946407Sjkh *
4046407Sjkh * $FreeBSD: head/sys/netgraph/netgraph.h 143385 2005-03-10 19:34:20Z glebius $
4148104Syokota * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $
4293011Samorita */
4348104Syokota
4446407Sjkh#ifndef _NETGRAPH_NETGRAPH_H_
4548104Syokota#define _NETGRAPH_NETGRAPH_H_
4648104Syokota
4748104Syokota#ifndef _KERNEL
4846407Sjkh#error "This file should not be included in user level programs"
4993011Samorita#endif
5046407Sjkh
5193011Samorita#include <sys/queue.h>
5293011Samorita#include <sys/lock.h>
5393011Samorita#include <sys/malloc.h>
5446407Sjkh#include <sys/module.h>
55166868Sphilip#include <sys/mutex.h>
56166868Sphilip/* debugging options */
57166868Sphilip#define NETGRAPH_DEBUG
58174985Swkoszek#define NG_SEPARATE_MALLOC	/* make modules use their own malloc types */
59166868Sphilip
60166868Sphilip/*
6193011Samorita * This defines the in-kernel binary interface version.
6293011Samorita * It is possible to change this but leave the external message
6393011Samorita * API the same. Each type also has it's own cookies for versioning as well.
6493011Samorita * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug
6593011Samorita * modules.
6693011Samorita */
6793011Samorita#define _NG_ABI_VERSION 10
6893011Samorita#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
6946689Sdes#define NG_ABI_VERSION	(_NG_ABI_VERSION + 0x10000)
7093011Samorita#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
7193011Samorita#define NG_ABI_VERSION	_NG_ABI_VERSION
72166868Sphilip#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
7346407Sjkh
7446689Sdes
7593011Samorita/*
7693011Samorita * Forward references for the basic structures so we can
7746899Sdes * define the typedefs and use them in the structures themselves.
7846689Sdes */
7993011Samoritastruct ng_hook ;
8093011Samoritastruct ng_node ;
8193011Samoritastruct ng_item ;
8293011Samoritatypedef	struct ng_item *item_p;
8393011Samoritatypedef struct ng_node *node_p;
8493011Samoritatypedef struct ng_hook *hook_p;
8593011Samorita
8693011Samorita/* node method definitions */
8793011Samoritatypedef	int	ng_constructor_t(node_p node);
8893011Samoritatypedef	int	ng_close_t(node_p node);
8946689Sdestypedef	int	ng_shutdown_t(node_p node);
9046899Sdestypedef	int	ng_newhook_t(node_p node, hook_p hook, const char *name);
9146689Sdestypedef	hook_p	ng_findhook_t(node_p node, const char *name);
9293011Samoritatypedef	int	ng_connect_t(hook_p hook);
9393011Samoritatypedef	int	ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
9493011Samoritatypedef	int	ng_rcvdata_t(hook_p hook, item_p item);
9593011Samoritatypedef	int	ng_disconnect_t(hook_p hook);
9693011Samoritatypedef	int	ng_rcvitem (node_p node, hook_p hook, item_p item);
97166868Sphilip
9893011Samorita/***********************************************************************
9993011Samorita ***************** Hook Structure and Methods **************************
10093011Samorita ***********************************************************************
10193011Samorita *
102166868Sphilip * Structure of a hook
10393011Samorita */
10493011Samoritastruct ng_hook {
10593011Samorita	char	hk_name[NG_HOOKSIZ];	/* what this node knows this link as */
10693011Samorita	void   *hk_private;		/* node dependant ID for this hook */
10793011Samorita	int	hk_flags;		/* info about this hook/link */
10893011Samorita	int	hk_refs;		/* dont actually free this till 0 */
10946899Sdes	struct	ng_hook *hk_peer;	/* the other end of this link */
11046407Sjkh	struct	ng_node *hk_node;	/* The node this hook is attached to */
11146407Sjkh	LIST_ENTRY(ng_hook) hk_hooks;	/* linked list of all hooks on node */
11246689Sdes	ng_rcvmsg_t	*hk_rcvmsg;	/* control messages come here */
11393011Samorita	ng_rcvdata_t	*hk_rcvdata;	/* data comes here */
11446899Sdes#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
115117833Snyan#define HK_MAGIC 0x78573011
11646899Sdes	int	hk_magic;
11793011Samorita	char	*lastfile;
11893011Samorita	int	lastline;
11993011Samorita	SLIST_ENTRY(ng_hook)	  hk_all;		/* all existing items */
12093011Samorita#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
121174985Swkoszek};
122174985Swkoszek/* Flags for a hook */
12393011Samorita#define HK_INVALID		0x0001	/* don't trust it! */
12493011Samorita#define HK_QUEUE		0x0002	/* queue for later delivery */
12593011Samorita#define HK_FORCE_WRITER		0x0004	/* Incoming data queued as a writer */
12693011Samorita#define HK_DEAD			0x0008	/* This is the dead hook.. don't free */
12793011Samorita
128174985Swkoszek/*
12993011Samorita * Public Methods for hook
13093011Samorita * If you can't do it with these you probably shouldn;t be doing it.
13193011Samorita */
13293011Samoritavoid ng_unref_hook(hook_p hook); /* don't move this */
13393011Samorita#define	_NG_HOOK_REF(hook)	atomic_add_int(&(hook)->hk_refs, 1)
13446899Sdes#define _NG_HOOK_NAME(hook)	((hook)->hk_name)
13546689Sdes#define _NG_HOOK_UNREF(hook)	ng_unref_hook(hook)
13646407Sjkh#define	_NG_HOOK_SET_PRIVATE(hook, val)	do {(hook)->hk_private = val;} while (0)
13746899Sdes#define	_NG_HOOK_SET_RCVMSG(hook, val)	do {(hook)->hk_rcvmsg = val;} while (0)
13846689Sdes#define	_NG_HOOK_SET_RCVDATA(hook, val)	do {(hook)->hk_rcvdata = val;} while (0)
13993011Samorita#define	_NG_HOOK_PRIVATE(hook)	((hook)->hk_private)
14046689Sdes#define _NG_HOOK_NOT_VALID(hook)	((hook)->hk_flags & HK_INVALID)
14193011Samorita#define _NG_HOOK_IS_VALID(hook)	(!((hook)->hk_flags & HK_INVALID))
14293011Samorita#define _NG_HOOK_NODE(hook)	((hook)->hk_node) /* only rvalue! */
14393011Samorita#define _NG_HOOK_PEER(hook)	((hook)->hk_peer) /* only rvalue! */
144174985Swkoszek#define _NG_HOOK_FORCE_WRITER(hook)				\
14593011Samorita		do { hook->hk_flags |= HK_FORCE_WRITER; } while (0)
146174985Swkoszek#define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0)
14793011Samorita
148174985Swkoszek/* Some shortcuts */
14993011Samorita#define NG_PEER_NODE(hook)	NG_HOOK_NODE(NG_HOOK_PEER(hook))
15093011Samorita#define NG_PEER_HOOK_NAME(hook)	NG_HOOK_NAME(NG_HOOK_PEER(hook))
15193011Samorita#define NG_PEER_NODE_NAME(hook)	NG_NODE_NAME(NG_PEER_NODE(hook))
15293011Samorita
15393011Samorita#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
15493011Samorita#define _NN_ __FILE__,__LINE__
15593011Samoritavoid	dumphook (hook_p hook, char *file, int line);
15693011Samoritastatic __inline void	_chkhook(hook_p hook, char *file, int line);
15793011Samoritastatic __inline void	_ng_hook_ref(hook_p hook, char * file, int line);
15893011Samoritastatic __inline char *	_ng_hook_name(hook_p hook, char * file, int line);
15993011Samoritastatic __inline void	_ng_hook_unref(hook_p hook, char * file, int line);
16093011Samoritastatic __inline void	_ng_hook_set_private(hook_p hook,
16193011Samorita				void * val, char * file, int line);
16293011Samoritastatic __inline void	_ng_hook_set_rcvmsg(hook_p hook,
16393011Samorita				ng_rcvmsg_t *val, char * file, int line);
16493011Samoritastatic __inline void	_ng_hook_set_rcvdata(hook_p hook,
16593011Samorita				ng_rcvdata_t *val, char * file, int line);
16693011Samoritastatic __inline void *	_ng_hook_private(hook_p hook, char * file, int line);
16793011Samoritastatic __inline int	_ng_hook_not_valid(hook_p hook, char * file, int line);
16893011Samoritastatic __inline int	_ng_hook_is_valid(hook_p hook, char * file, int line);
16993011Samoritastatic __inline node_p	_ng_hook_node(hook_p hook, char * file, int line);
17093011Samoritastatic __inline hook_p	_ng_hook_peer(hook_p hook, char * file, int line);
17193011Samoritastatic __inline void	_ng_hook_force_writer(hook_p hook, char * file,
17293011Samorita					int line);
17393011Samoritastatic __inline void	_ng_hook_force_queue(hook_p hook, char * file, int line);
17493011Samorita
17593011Samoritastatic void __inline
17693011Samorita_chkhook(hook_p hook, char *file, int line)
17793011Samorita{
17893011Samorita	if (hook->hk_magic != HK_MAGIC) {
17993011Samorita		printf("Accessing freed hook ");
18093011Samorita		dumphook(hook, file, line);
18193011Samorita	}
18246407Sjkh	hook->lastline = line;
18346407Sjkh	hook->lastfile = file;
18493011Samorita}
18593011Samorita
18693011Samoritastatic __inline void
18793011Samorita_ng_hook_ref(hook_p hook, char * file, int line)
18893011Samorita{
18993011Samorita	_chkhook(hook, file, line);
19093011Samorita	_NG_HOOK_REF(hook);
19146407Sjkh}
19293011Samorita
19393011Samoritastatic __inline char *
19493011Samorita_ng_hook_name(hook_p hook, char * file, int line)
19593011Samorita{
19693011Samorita	_chkhook(hook, file, line);
19746407Sjkh	return (_NG_HOOK_NAME(hook));
19846407Sjkh}
19946407Sjkh
200static __inline void
201_ng_hook_unref(hook_p hook, char * file, int line)
202{
203	_chkhook(hook, file, line);
204	_NG_HOOK_UNREF(hook);
205}
206
207static __inline void
208_ng_hook_set_private(hook_p hook, void *val, char * file, int line)
209{
210	_chkhook(hook, file, line);
211	_NG_HOOK_SET_PRIVATE(hook, val);
212}
213
214static __inline void
215_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line)
216{
217	_chkhook(hook, file, line);
218	_NG_HOOK_SET_RCVMSG(hook, val);
219}
220
221static __inline void
222_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line)
223{
224	_chkhook(hook, file, line);
225	_NG_HOOK_SET_RCVDATA(hook, val);
226}
227
228static __inline void *
229_ng_hook_private(hook_p hook, char * file, int line)
230{
231	_chkhook(hook, file, line);
232	return (_NG_HOOK_PRIVATE(hook));
233}
234
235static __inline int
236_ng_hook_not_valid(hook_p hook, char * file, int line)
237{
238	_chkhook(hook, file, line);
239	return (_NG_HOOK_NOT_VALID(hook));
240}
241
242static __inline int
243_ng_hook_is_valid(hook_p hook, char * file, int line)
244{
245	_chkhook(hook, file, line);
246	return (_NG_HOOK_IS_VALID(hook));
247}
248
249static __inline node_p
250_ng_hook_node(hook_p hook, char * file, int line)
251{
252	_chkhook(hook, file, line);
253	return (_NG_HOOK_NODE(hook));
254}
255
256static __inline hook_p
257_ng_hook_peer(hook_p hook, char * file, int line)
258{
259	_chkhook(hook, file, line);
260	return (_NG_HOOK_PEER(hook));
261}
262
263static __inline void
264_ng_hook_force_writer(hook_p hook, char * file, int line)
265{
266	_chkhook(hook, file, line);
267	_NG_HOOK_FORCE_WRITER(hook);
268}
269
270static __inline void
271_ng_hook_force_queue(hook_p hook, char * file, int line)
272{
273	_chkhook(hook, file, line);
274	_NG_HOOK_FORCE_QUEUE(hook);
275}
276
277
278#define	NG_HOOK_REF(hook)		_ng_hook_ref(hook, _NN_)
279#define NG_HOOK_NAME(hook)		_ng_hook_name(hook, _NN_)
280#define NG_HOOK_UNREF(hook)		_ng_hook_unref(hook, _NN_)
281#define	NG_HOOK_SET_PRIVATE(hook, val)	_ng_hook_set_private(hook, val, _NN_)
282#define	NG_HOOK_SET_RCVMSG(hook, val)	_ng_hook_set_rcvmsg(hook, val, _NN_)
283#define	NG_HOOK_SET_RCVDATA(hook, val)	_ng_hook_set_rcvdata(hook, val, _NN_)
284#define	NG_HOOK_PRIVATE(hook)		_ng_hook_private(hook, _NN_)
285#define NG_HOOK_NOT_VALID(hook)		_ng_hook_not_valid(hook, _NN_)
286#define NG_HOOK_IS_VALID(hook)		_ng_hook_is_valid(hook, _NN_)
287#define NG_HOOK_NODE(hook)		_ng_hook_node(hook, _NN_)
288#define NG_HOOK_PEER(hook)		_ng_hook_peer(hook, _NN_)
289#define NG_HOOK_FORCE_WRITER(hook)	_ng_hook_force_writer(hook, _NN_)
290#define NG_HOOK_FORCE_QUEUE(hook)	_ng_hook_force_queue(hook, _NN_)
291
292#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
293
294#define	NG_HOOK_REF(hook)		_NG_HOOK_REF(hook)
295#define NG_HOOK_NAME(hook)		_NG_HOOK_NAME(hook)
296#define NG_HOOK_UNREF(hook)		_NG_HOOK_UNREF(hook)
297#define	NG_HOOK_SET_PRIVATE(hook, val)	_NG_HOOK_SET_PRIVATE(hook, val)
298#define	NG_HOOK_SET_RCVMSG(hook, val)	_NG_HOOK_SET_RCVMSG(hook, val)
299#define	NG_HOOK_SET_RCVDATA(hook, val)	_NG_HOOK_SET_RCVDATA(hook, val)
300#define	NG_HOOK_PRIVATE(hook)		_NG_HOOK_PRIVATE(hook)
301#define NG_HOOK_NOT_VALID(hook)		_NG_HOOK_NOT_VALID(hook)
302#define NG_HOOK_IS_VALID(hook)		_NG_HOOK_IS_VALID(hook)
303#define NG_HOOK_NODE(hook)		_NG_HOOK_NODE(hook)
304#define NG_HOOK_PEER(hook)		_NG_HOOK_PEER(hook)
305#define NG_HOOK_FORCE_WRITER(hook)	_NG_HOOK_FORCE_WRITER(hook)
306#define NG_HOOK_FORCE_QUEUE(hook)	_NG_HOOK_FORCE_QUEUE(hook)
307
308#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
309
310/***********************************************************************
311 ***************** Node Structure and Methods **************************
312 ***********************************************************************
313 * Structure of a node
314 * including the eembedded queue structure.
315 *
316 * The structure for queueing Netgraph request items
317 * embedded in the node structure
318 */
319struct ng_queue {
320	u_long          q_flags;
321	struct mtx      q_mtx;
322	item_p queue;
323	item_p *last;
324	struct ng_node *q_node;		/* find the front of the node.. */
325};
326
327struct ng_node {
328	char	nd_name[NG_NODESIZ];	/* optional globally unique name */
329	struct	ng_type *nd_type;	/* the installed 'type' */
330	int	nd_flags;		/* see below for bit definitions */
331	int	nd_refs;		/* # of references to this node */
332	int	nd_numhooks;		/* number of hooks */
333	void   *nd_private;		/* node type dependant node ID */
334	ng_ID_t	nd_ID;			/* Unique per node */
335	LIST_HEAD(hooks, ng_hook) nd_hooks;	/* linked list of node hooks */
336	LIST_ENTRY(ng_node)	  nd_nodes;	/* linked list of all nodes */
337	LIST_ENTRY(ng_node)	  nd_idnodes;	/* ID hash collision list */
338	TAILQ_ENTRY(ng_node)	  nd_work;	/* nodes with work to do */
339	struct	ng_queue	  nd_input_queue; /* input queue for locking */
340#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
341#define ND_MAGIC 0x59264837
342	int	nd_magic;
343	char	*lastfile;
344	int	lastline;
345	SLIST_ENTRY(ng_node)	  nd_all;	/* all existing nodes */
346#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
347};
348
349/* Flags for a node */
350#define NGF_INVALID	0x00000001	/* free when refs go to 0 */
351#define NG_INVALID	NGF_INVALID	/* compat for old code */
352#define NGF_WORKQ	0x00000002	/* node is on the work queue */
353#define NG_WORKQ	NGF_WORKQ	/* compat for old code */
354#define NGF_FORCE_WRITER	0x00000004	/* Never multithread this node */
355#define NG_FORCE_WRITER	NGF_FORCE_WRITER /* compat for old code */
356#define NGF_CLOSING	0x00000008	/* ng_rmnode() at work */
357#define NG_CLOSING	NGF_CLOSING	/* compat for old code */
358#define NGF_REALLY_DIE	0x00000010	/* "persistent" node is unloading */
359#define NG_REALLY_DIE	NGF_REALLY_DIE	/* compat for old code */
360#define NGF_TYPE1	0x10000000	/* reserved for type specific storage */
361#define NGF_TYPE2	0x20000000	/* reserved for type specific storage */
362#define NGF_TYPE3	0x40000000	/* reserved for type specific storage */
363#define NGF_TYPE4	0x80000000	/* reserved for type specific storage */
364
365/*
366 * Public methods for nodes.
367 * If you can't do it with these you probably shouldn't be doing it.
368 */
369int	ng_unref_node(node_p node); /* don't move this */
370#define _NG_NODE_NAME(node)	((node)->nd_name + 0)
371#define _NG_NODE_HAS_NAME(node)	((node)->nd_name[0] + 0)
372#define _NG_NODE_ID(node)	((node)->nd_ID + 0)
373#define	_NG_NODE_REF(node)	atomic_add_int(&(node)->nd_refs, 1)
374#define	_NG_NODE_UNREF(node)	ng_unref_node(node)
375#define	_NG_NODE_SET_PRIVATE(node, val)	do {(node)->nd_private = val;} while (0)
376#define	_NG_NODE_PRIVATE(node)	((node)->nd_private)
377#define _NG_NODE_IS_VALID(node)	(!((node)->nd_flags & NGF_INVALID))
378#define _NG_NODE_NOT_VALID(node)	((node)->nd_flags & NGF_INVALID)
379#define _NG_NODE_NUMHOOKS(node)	((node)->nd_numhooks + 0) /* rvalue */
380#define _NG_NODE_FORCE_WRITER(node)					\
381	do{ node->nd_flags |= NGF_FORCE_WRITER; }while (0)
382#define _NG_NODE_REALLY_DIE(node)					\
383	do{ node->nd_flags |= (NGF_REALLY_DIE|NGF_INVALID); }while (0)
384#define _NG_NODE_REVIVE(node) \
385	do { node->nd_flags &= ~NGF_INVALID; } while (0)
386/*
387 * The hook iterator.
388 * This macro will call a function of type ng_fn_eachhook for each
389 * hook attached to the node. If the function returns 0, then the
390 * iterator will stop and return a pointer to the hook that returned 0.
391 */
392typedef	int	ng_fn_eachhook(hook_p hook, void* arg);
393#define _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			\
394	do {								\
395		hook_p _hook;						\
396		(rethook) = NULL;					\
397		LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) {	\
398			if ((fn)(_hook, arg) == 0) {			\
399				(rethook) = _hook;			\
400				break;					\
401			}						\
402		}							\
403	} while (0)
404
405#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
406void	dumpnode(node_p node, char *file, int line);
407static void __inline _chknode(node_p node, char *file, int line);
408static __inline char * _ng_node_name(node_p node, char *file, int line);
409static __inline int _ng_node_has_name(node_p node, char *file, int line);
410static __inline ng_ID_t _ng_node_id(node_p node, char *file, int line);
411void ng_ref_node(node_p node);
412static __inline void _ng_node_ref(node_p node, char *file, int line);
413static __inline int _ng_node_unref(node_p node, char *file, int line);
414static __inline void _ng_node_set_private(node_p node, void * val,
415							char *file, int line);
416static __inline void * _ng_node_private(node_p node, char *file, int line);
417static __inline int _ng_node_is_valid(node_p node, char *file, int line);
418static __inline int _ng_node_not_valid(node_p node, char *file, int line);
419static __inline int _ng_node_numhooks(node_p node, char *file, int line);
420static __inline void _ng_node_force_writer(node_p node, char *file, int line);
421static __inline hook_p _ng_node_foreach_hook(node_p node,
422			ng_fn_eachhook *fn, void *arg, char *file, int line);
423static __inline void _ng_node_revive(node_p node, char *file, int line);
424
425static void __inline
426_chknode(node_p node, char *file, int line)
427{
428	if (node->nd_magic != ND_MAGIC) {
429		printf("Accessing freed node ");
430		dumpnode(node, file, line);
431	}
432	node->lastline = line;
433	node->lastfile = file;
434}
435
436static __inline char *
437_ng_node_name(node_p node, char *file, int line)
438{
439	_chknode(node, file, line);
440	return(_NG_NODE_NAME(node));
441}
442
443static __inline int
444_ng_node_has_name(node_p node, char *file, int line)
445{
446	_chknode(node, file, line);
447	return(_NG_NODE_HAS_NAME(node));
448}
449
450static __inline ng_ID_t
451_ng_node_id(node_p node, char *file, int line)
452{
453	_chknode(node, file, line);
454	return(_NG_NODE_ID(node));
455}
456
457static __inline void
458_ng_node_ref(node_p node, char *file, int line)
459{
460	_chknode(node, file, line);
461	/*_NG_NODE_REF(node);*/
462	ng_ref_node(node);
463}
464
465static __inline int
466_ng_node_unref(node_p node, char *file, int line)
467{
468	_chknode(node, file, line);
469	return (_NG_NODE_UNREF(node));
470}
471
472static __inline void
473_ng_node_set_private(node_p node, void * val, char *file, int line)
474{
475	_chknode(node, file, line);
476	_NG_NODE_SET_PRIVATE(node, val);
477}
478
479static __inline void *
480_ng_node_private(node_p node, char *file, int line)
481{
482	_chknode(node, file, line);
483	return (_NG_NODE_PRIVATE(node));
484}
485
486static __inline int
487_ng_node_is_valid(node_p node, char *file, int line)
488{
489	_chknode(node, file, line);
490	return(_NG_NODE_IS_VALID(node));
491}
492
493static __inline int
494_ng_node_not_valid(node_p node, char *file, int line)
495{
496	_chknode(node, file, line);
497	return(_NG_NODE_NOT_VALID(node));
498}
499
500static __inline int
501_ng_node_numhooks(node_p node, char *file, int line)
502{
503	_chknode(node, file, line);
504	return(_NG_NODE_NUMHOOKS(node));
505}
506
507static __inline void
508_ng_node_force_writer(node_p node, char *file, int line)
509{
510	_chknode(node, file, line);
511	_NG_NODE_FORCE_WRITER(node);
512}
513
514static __inline void
515_ng_node_really_die(node_p node, char *file, int line)
516{
517	_chknode(node, file, line);
518	_NG_NODE_REALLY_DIE(node);
519}
520
521static __inline void
522_ng_node_revive(node_p node, char *file, int line)
523{
524	_chknode(node, file, line);
525	_NG_NODE_REVIVE(node);
526}
527
528static __inline hook_p
529_ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg,
530						char *file, int line)
531{
532	hook_p hook;
533	_chknode(node, file, line);
534	_NG_NODE_FOREACH_HOOK(node, fn, arg, hook);
535	return (hook);
536}
537
538#define NG_NODE_NAME(node)		_ng_node_name(node, _NN_)
539#define NG_NODE_HAS_NAME(node)		_ng_node_has_name(node, _NN_)
540#define NG_NODE_ID(node)		_ng_node_id(node, _NN_)
541#define NG_NODE_REF(node)		_ng_node_ref(node, _NN_)
542#define	NG_NODE_UNREF(node)		_ng_node_unref(node, _NN_)
543#define	NG_NODE_SET_PRIVATE(node, val)	_ng_node_set_private(node, val, _NN_)
544#define	NG_NODE_PRIVATE(node)		_ng_node_private(node, _NN_)
545#define NG_NODE_IS_VALID(node)		_ng_node_is_valid(node, _NN_)
546#define NG_NODE_NOT_VALID(node)		_ng_node_not_valid(node, _NN_)
547#define NG_NODE_FORCE_WRITER(node) 	_ng_node_force_writer(node, _NN_)
548#define NG_NODE_REALLY_DIE(node) 	_ng_node_really_die(node, _NN_)
549#define NG_NODE_NUMHOOKS(node)		_ng_node_numhooks(node, _NN_)
550#define NG_NODE_REVIVE(node)		_ng_node_revive(node, _NN_)
551#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			      \
552	do {								      \
553		rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \
554	} while (0)
555
556#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
557
558#define NG_NODE_NAME(node)		_NG_NODE_NAME(node)
559#define NG_NODE_HAS_NAME(node)		_NG_NODE_HAS_NAME(node)
560#define NG_NODE_ID(node)		_NG_NODE_ID(node)
561#define	NG_NODE_REF(node)		_NG_NODE_REF(node)
562#define	NG_NODE_UNREF(node)		_NG_NODE_UNREF(node)
563#define	NG_NODE_SET_PRIVATE(node, val)	_NG_NODE_SET_PRIVATE(node, val)
564#define	NG_NODE_PRIVATE(node)		_NG_NODE_PRIVATE(node)
565#define NG_NODE_IS_VALID(node)		_NG_NODE_IS_VALID(node)
566#define NG_NODE_NOT_VALID(node)		_NG_NODE_NOT_VALID(node)
567#define NG_NODE_FORCE_WRITER(node) 	_NG_NODE_FORCE_WRITER(node)
568#define NG_NODE_REALLY_DIE(node) 	_NG_NODE_REALLY_DIE(node)
569#define NG_NODE_NUMHOOKS(node)		_NG_NODE_NUMHOOKS(node)
570#define NG_NODE_REVIVE(node)		_NG_NODE_REVIVE(node)
571#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)			\
572		_NG_NODE_FOREACH_HOOK(node, fn, arg, rethook)
573#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
574
575/***********************************************************************
576 ************* Node Queue and Item Structures and Methods **************
577 ***********************************************************************
578 *
579 */
580typedef	void	ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2);
581struct ng_item {
582	u_long	el_flags;
583	item_p	el_next;
584	node_p	el_dest; /* The node it will be applied against (or NULL) */
585	hook_p	el_hook; /* Entering hook. Optional in Control messages */
586	union {
587		struct mbuf	*da_m;
588		struct {
589			struct ng_mesg	*msg_msg;
590			ng_ID_t		msg_retaddr;
591		} msg;
592		struct {
593			ng_item_fn	*fn_fn;
594			void 		*fn_arg1;
595			int		fn_arg2;
596		} fn;
597	} body;
598#ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
599	char *lastfile;
600	int  lastline;
601	TAILQ_ENTRY(ng_item)	  all;		/* all existing items */
602#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
603};
604
605#define NGQF_TYPE	0x03		/* MASK of content definition */
606#define NGQF_MESG	0x00		/* the queue element is a message */
607#define NGQF_DATA	0x01		/* the queue element is data */
608#define NGQF_FN		0x02		/* the queue element is a function */
609#define NGQF_UNDEF	0x03		/* UNDEFINED */
610
611#define NGQF_RW		0x04		/* MASK for queue entry read/write */
612#define NGQF_READER	0x04		/* queued as a reader */
613#define NGQF_WRITER	0x00		/* queued as a writer */
614
615#define NGQF_FREE	0x08
616
617/*
618 * Get the mbuf (etc) out of an item.
619 * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM()
620 * with it, (to avoid freeing the things twice).
621 * If you don't want to zero out the item then realise that the
622 * item still owns it.
623 * Retaddr is different. There are no references on that. It's just a number.
624 * The debug versions must be either all used everywhere or not at all.
625 */
626
627#define _NGI_M(i) ((i)->body.da_m)
628#define _NGI_MSG(i) ((i)->body.msg.msg_msg)
629#define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr)
630#define	_NGI_FN(i) ((i)->body.fn.fn_fn)
631#define	_NGI_ARG1(i) ((i)->body.fn.fn_arg1)
632#define	_NGI_ARG2(i) ((i)->body.fn.fn_arg2)
633#define	_NGI_NODE(i) ((i)->el_dest)
634#define	_NGI_HOOK(i) ((i)->el_hook)
635#define	_NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0)
636#define	_NGI_CLR_HOOK(i)   do {						\
637		hook_p _hook = _NGI_HOOK(i);				\
638		if (_hook) {						\
639			_NG_HOOK_UNREF(_hook);				\
640			_NGI_HOOK(i) = NULL;				\
641		}							\
642	} while (0)
643#define	_NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0)
644#define	_NGI_CLR_NODE(i)   do {						\
645		node_p _node = _NGI_NODE(i);				\
646		if (_node) {						\
647			_NG_NODE_UNREF(_node);				\
648			_NGI_NODE(i) = NULL;				\
649		}							\
650	} while (0)
651
652#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
653void				dumpitem(item_p item, char *file, int line);
654static __inline void		_ngi_check(item_p item, char *file, int line) ;
655static __inline struct mbuf **	_ngi_m(item_p item, char *file, int line) ;
656static __inline ng_ID_t *	_ngi_retaddr(item_p item, char *file, int line);
657static __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ;
658static __inline ng_item_fn **	_ngi_fn(item_p item, char *file, int line) ;
659static __inline void **		_ngi_arg1(item_p item, char *file, int line) ;
660static __inline int *		_ngi_arg2(item_p item, char *file, int line) ;
661static __inline node_p		_ngi_node(item_p item, char *file, int line);
662static __inline hook_p		_ngi_hook(item_p item, char *file, int line);
663
664static __inline void
665_ngi_check(item_p item, char *file, int line)
666{
667	if (item->el_flags & NGQF_FREE) {
668		dumpitem(item, file, line);
669		panic ("free item!");
670	}
671	(item)->lastline = line;
672	(item)->lastfile = file;
673}
674
675static __inline struct mbuf **
676_ngi_m(item_p item, char *file, int line)
677{
678	_ngi_check(item, file, line);
679	return (&_NGI_M(item));
680}
681
682static __inline struct ng_mesg **
683_ngi_msg(item_p item, char *file, int line)
684{
685	_ngi_check(item, file, line);
686	return (&_NGI_MSG(item));
687}
688
689static __inline ng_ID_t *
690_ngi_retaddr(item_p item, char *file, int line)
691{
692	_ngi_check(item, file, line);
693	return (&_NGI_RETADDR(item));
694}
695
696static __inline ng_item_fn **
697_ngi_fn(item_p item, char *file, int line)
698{
699	_ngi_check(item, file, line);
700	return (&_NGI_FN(item));
701}
702
703static __inline void **
704_ngi_arg1(item_p item, char *file, int line)
705{
706	_ngi_check(item, file, line);
707	return (&_NGI_ARG1(item));
708}
709
710static __inline int *
711_ngi_arg2(item_p item, char *file, int line)
712{
713	_ngi_check(item, file, line);
714	return (&_NGI_ARG2(item));
715}
716
717static __inline node_p
718_ngi_node(item_p item, char *file, int line)
719{
720	_ngi_check(item, file, line);
721	return (_NGI_NODE(item));
722}
723
724static __inline hook_p
725_ngi_hook(item_p item, char *file, int line)
726{
727	_ngi_check(item, file, line);
728	return (_NGI_HOOK(item));
729}
730
731#define NGI_M(i)	(*_ngi_m(i, _NN_))
732#define NGI_MSG(i)	(*_ngi_msg(i, _NN_))
733#define NGI_RETADDR(i)	(*_ngi_retaddr(i, _NN_))
734#define NGI_FN(i)	(*_ngi_fn(i, _NN_))
735#define NGI_ARG1(i)	(*_ngi_arg1(i, _NN_))
736#define NGI_ARG2(i)	(*_ngi_arg2(i, _NN_))
737#define NGI_HOOK(i)	_ngi_hook(i, _NN_)
738#define NGI_NODE(i)	_ngi_node(i, _NN_)
739#define	NGI_SET_HOOK(i,h)						\
740	do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0)
741#define	NGI_CLR_HOOK(i)							\
742	do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0)
743#define	NGI_SET_NODE(i,n)						\
744	do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0)
745#define	NGI_CLR_NODE(i)							\
746	do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0)
747
748#define NG_FREE_ITEM(item)						\
749	do {								\
750		_ngi_check(item, _NN_);					\
751		ng_free_item((item));					\
752	} while (0)
753
754#define	SAVE_LINE(item)							\
755	do {								\
756		(item)->lastline = __LINE__;				\
757		(item)->lastfile = __FILE__;				\
758	} while (0)
759
760#else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
761
762#define NGI_M(i)	_NGI_M(i)
763#define NGI_MSG(i)	_NGI_MSG(i)
764#define NGI_RETADDR(i)	_NGI_RETADDR(i)
765#define NGI_FN(i)	_NGI_FN(i)
766#define NGI_ARG1(i)	_NGI_ARG1(i)
767#define NGI_ARG2(i)	_NGI_ARG2(i)
768#define	NGI_NODE(i)	_NGI_NODE(i)
769#define	NGI_HOOK(i)	_NGI_HOOK(i)
770#define	NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h)
771#define	NGI_CLR_HOOK(i)	  _NGI_CLR_HOOK(i)
772#define	NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n)
773#define	NGI_CLR_NODE(i)	  _NGI_CLR_NODE(i)
774
775#define	NG_FREE_ITEM(item)	ng_free_item((item))
776#define	SAVE_LINE(item)		do {} while (0)
777
778#endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
779
780#define NGI_GET_M(i,m)							\
781	do {								\
782		(m) = NGI_M(i);						\
783		_NGI_M(i) = NULL;					\
784	} while (0)
785
786#define NGI_GET_MSG(i,m)						\
787	do {								\
788		(m) = NGI_MSG(i);					\
789		_NGI_MSG(i) = NULL;					\
790	} while (0)
791
792#define NGI_GET_NODE(i,n)	/* YOU NOW HAVE THE REFERENCE */	\
793	do {								\
794		(n) = NGI_NODE(i);					\
795		_NGI_NODE(i) = NULL;					\
796	} while (0)
797
798#define NGI_GET_HOOK(i,h)						\
799	do {								\
800		(h) = NGI_HOOK(i);					\
801		_NGI_HOOK(i) = NULL;					\
802	} while (0)
803
804
805/**********************************************************************
806* Data macros.  Send, manipulate and free.
807**********************************************************************/
808/*
809 * Assuming the data is already ok, just set the new address and send
810 */
811#define NG_FWD_ITEM_HOOK(error, item, hook)				\
812	do {								\
813		(error) =						\
814		    ng_address_hook(NULL, (item), (hook), 0);	\
815		if (error == 0) {					\
816			SAVE_LINE(item);				\
817			(error) = ng_snd_item((item), 0);		\
818		}							\
819		(item) = NULL;						\
820	} while (0)
821
822/*
823 * Forward a data packet. Mbuf pointer is updated to new value. We
824 * presume you dealt with the old one when you update it to the new one
825 * (or it maybe the old one). We got a packet and possibly had to modify
826 * the mbuf. You should probably use NGI_GET_M() if you are going to use
827 * this too.
828 */
829#define NG_FWD_NEW_DATA(error, item, hook, m)				\
830	do {								\
831		NGI_M(item) = (m);					\
832		(m) = NULL;						\
833		NG_FWD_ITEM_HOOK(error, item, hook);			\
834	} while (0)
835
836/* Send a previously unpackaged mbuf. XXX: This should be called
837 * NG_SEND_DATA in future, but this name is kept for compatibility
838 * reasons.
839 */
840#define NG_SEND_DATA_ONLY(error, hook, m)				\
841	do {								\
842		item_p _item;						\
843		if ((_item = ng_package_data((m), NULL))) {		\
844			NG_FWD_ITEM_HOOK(error, _item, hook);		\
845		} else {						\
846			(error) = ENOMEM;				\
847		}							\
848		(m) = NULL;						\
849	} while (0)
850
851#define NG_SEND_DATA(error, hook, m, x) NG_SEND_DATA_ONLY(error, hook, m)
852
853#define NG_FREE_MSG(msg)						\
854	do {								\
855		if ((msg)) {						\
856			FREE((msg), M_NETGRAPH_MSG);			\
857			(msg) = NULL;					\
858		}	 						\
859	} while (0)
860
861#define NG_FREE_M(m)							\
862	do {								\
863		if ((m)) {						\
864			m_freem((m));					\
865			(m) = NULL;					\
866		}							\
867	} while (0)
868
869/*****************************************
870* Message macros
871*****************************************/
872
873#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)		\
874	do {								\
875		item_p _item;						\
876		if ((_item = ng_package_msg(msg)) == NULL) {		\
877			(msg) = NULL;					\
878			(error) = ENOMEM;				\
879			break;						\
880		}							\
881		if (((error) = ng_address_hook((here), (_item),		\
882					(hook), (retaddr))) == 0) {	\
883			SAVE_LINE(_item);				\
884			(error) = ng_snd_item((_item), 0);		\
885		}							\
886		(msg) = NULL;						\
887	} while (0)
888
889#define NG_SEND_MSG_PATH(error, here, msg, path, retaddr)		\
890	do {								\
891		item_p _item;						\
892		if ((_item = ng_package_msg(msg)) == NULL) {		\
893			(msg) = NULL;					\
894			(error) = ENOMEM;				\
895			break;						\
896		}							\
897		if (((error) = ng_address_path((here), (_item),		\
898					(path), (retaddr))) == 0) {	\
899			SAVE_LINE(_item);				\
900			(error) = ng_snd_item((_item), 0);		\
901		}							\
902		(msg) = NULL;						\
903	} while (0)
904
905#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr)			\
906	do {								\
907		item_p _item;						\
908		if ((_item = ng_package_msg(msg)) == NULL) {		\
909			(msg) = NULL;					\
910			(error) = ENOMEM;				\
911			break;						\
912		}							\
913		if (((error) = ng_address_ID((here), (_item),		\
914					(ID), (retaddr))) == 0) {	\
915			SAVE_LINE(_item);				\
916			(error) = ng_snd_item((_item), 0);		\
917		}							\
918		(msg) = NULL;						\
919	} while (0)
920
921/*
922 * Redirect the message to the next hop using the given hook.
923 * ng_retarget_msg() frees the item if there is an error
924 * and returns an error code.  It returns 0 on success.
925 */
926#define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr)		\
927	do {								\
928		if (((error) = ng_address_hook((here), (item),		\
929					(hook), (retaddr))) == 0) {	\
930			SAVE_LINE(item);				\
931			(error) = ng_snd_item((item), 0);		\
932		}							\
933		(item) = NULL;						\
934	} while (0)
935
936/*
937 * Send a queue item back to it's originator with a response message.
938 * Assume original message was removed and freed separatly.
939 */
940#define NG_RESPOND_MSG(error, here, item, resp)				\
941	do {								\
942		if (resp) {						\
943			ng_ID_t _dest = NGI_RETADDR(item);		\
944			NGI_RETADDR(item) = 0;				\
945			NGI_MSG(item) = resp;				\
946			if ((ng_address_ID((here), (item),		\
947					_dest, 0)) == 0) {		\
948				SAVE_LINE(item);			\
949				(error) = ng_snd_item((item), 1);	\
950			} else {					\
951				NG_FREE_ITEM(item);			\
952				(error) = EINVAL;			\
953			}						\
954		} else {						\
955			NG_FREE_ITEM(item);				\
956		}							\
957		(item) = NULL;						\
958	} while (0)
959
960
961/***********************************************************************
962 ******** Structures Definitions and Macros for defining a node  *******
963 ***********************************************************************
964 *
965 * Here we define the structures needed to actually define a new node
966 * type.
967 */
968
969/*
970 * Command list -- each node type specifies the command that it knows
971 * how to convert between ASCII and binary using an array of these.
972 * The last element in the array must be a terminator with cookie=0.
973 */
974
975struct ng_cmdlist {
976	u_int32_t			cookie;		/* command typecookie */
977	int				cmd;		/* command number */
978	const char			*name;		/* command name */
979	const struct ng_parse_type	*mesgType;	/* args if !NGF_RESP */
980	const struct ng_parse_type	*respType;	/* args if NGF_RESP */
981};
982
983/*
984 * Structure of a node type
985 * If data is sent to the "rcvdata()" entrypoint then the system
986 * may decide to defer it until later by queing it with the normal netgraph
987 * input queuing system.  This is decidde by the HK_QUEUE flag being set in
988 * the flags word of the peer (receiving) hook. The dequeuing mechanism will
989 * ensure it is not requeued again.
990 * Note the input queueing system is to allow modules
991 * to 'release the stack' or to pass data across spl layers.
992 * The data will be redelivered as soon as the NETISR code runs
993 * which may be almost immediatly.  A node may also do it's own queueing
994 * for other reasons (e.g. device output queuing).
995 */
996struct ng_type {
997
998	u_int32_t	version; 	/* must equal NG_API_VERSION */
999	const char	*name;		/* Unique type name */
1000	modeventhand_t	mod_event;	/* Module event handler (optional) */
1001	ng_constructor_t *constructor;	/* Node constructor */
1002	ng_rcvmsg_t	*rcvmsg;	/* control messages come here */
1003	ng_close_t	*close;		/* warn about forthcoming shutdown */
1004	ng_shutdown_t	*shutdown;	/* reset, and free resources */
1005	ng_newhook_t	*newhook;	/* first notification of new hook */
1006	ng_findhook_t	*findhook;	/* only if you have lots of hooks */
1007	ng_connect_t	*connect;	/* final notification of new hook */
1008	ng_rcvdata_t	*rcvdata;	/* data comes here */
1009	ng_disconnect_t	*disconnect;	/* notify on disconnect */
1010
1011	const struct	ng_cmdlist *cmdlist;	/* commands we can convert */
1012
1013	/* R/W data private to the base netgraph code DON'T TOUCH! */
1014	LIST_ENTRY(ng_type) types;		/* linked list of all types */
1015	int		    refs;		/* number of instances */
1016};
1017
1018/*
1019 * Use the NETGRAPH_INIT() macro to link a node type into the
1020 * netgraph system. This works for types compiled into the kernel
1021 * as well as KLD modules. The first argument should be the type
1022 * name (eg, echo) and the second a pointer to the type struct.
1023 *
1024 * If a different link time is desired, e.g., a device driver that
1025 * needs to install its netgraph type before probing, use the
1026 * NETGRAPH_INIT_ORDERED() macro instead. Deivce drivers probably
1027 * want to use SI_SUB_DRIVERS instead of SI_SUB_PSEUDO.
1028 */
1029
1030#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order)	\
1031static moduledata_t ng_##typename##_mod = {				\
1032	"ng_" #typename,						\
1033	ng_mod_event,							\
1034	(typestructp)							\
1035};									\
1036DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order);		\
1037MODULE_DEPEND(ng_##typename, netgraph,	NG_ABI_VERSION,			\
1038					NG_ABI_VERSION,			\
1039					NG_ABI_VERSION)
1040
1041#define NETGRAPH_INIT(tn, tp)						\
1042	NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY)
1043
1044/* Special malloc() type for netgraph structs and ctrl messages */
1045/* Only these two types should be visible to nodes */
1046MALLOC_DECLARE(M_NETGRAPH);
1047MALLOC_DECLARE(M_NETGRAPH_MSG);
1048
1049/* declare the base of the netgraph sysclt hierarchy */
1050/* but only if this file cares about sysctls */
1051#ifdef	SYSCTL_DECL
1052SYSCTL_DECL(_net_graph);
1053#endif
1054
1055/*
1056 * Methods that the nodes can use.
1057 * Many of these methods should usually NOT be used directly but via
1058 * Macros above.
1059 */
1060int	ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr);
1061int	ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
1062int	ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr);
1063int	ng_bypass(hook_p hook1, hook_p hook2);
1064hook_p	ng_findhook(node_p node, const char *name);
1065struct	ng_type *ng_findtype(const char *type);
1066int	ng_make_node_common(struct ng_type *typep, node_p *nodep);
1067int	ng_name_node(node_p node, const char *name);
1068int	ng_newtype(struct ng_type *tp);
1069ng_ID_t ng_node2ID(node_p node);
1070item_p	ng_package_data(struct mbuf *m, void *dummy);
1071item_p	ng_package_msg(struct ng_mesg *msg);
1072item_p	ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg);
1073void	ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr);
1074int	ng_rmhook_self(hook_p hook);	/* if a node wants to kill a hook */
1075int	ng_rmnode_self(node_p here);	/* if a node wants to suicide */
1076int	ng_rmtype(struct ng_type *tp);
1077int	ng_snd_item(item_p item, int queue);
1078int 	ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn,
1079	void *arg1, int arg2);
1080int	ng_uncallout(struct callout *c, node_p node);
1081int	ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
1082	    ng_item_fn *fn, void * arg1, int arg2);
1083#define	ng_callout_init(c)	callout_init(c, CALLOUT_MPSAFE)
1084
1085/*
1086 * prototypes the user should DEFINITELY not use directly
1087 */
1088void	ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */
1089int	ng_mod_event(module_t mod, int what, void *arg);
1090
1091/*
1092 * Tag definitions and constants
1093 */
1094
1095#define	NG_TAG_PRIO	1
1096
1097struct ng_tag_prio {
1098	struct m_tag	tag;
1099	char	priority;
1100	char	discardability;
1101};
1102
1103#define	NG_PRIO_CUTOFF		32
1104#define	NG_PRIO_LINKSTATE	64
1105
1106/* Macros and declarations to keep compatibility with metadata, which
1107 * is obsoleted now. To be deleted.
1108 */
1109typedef void *meta_p;
1110#define _NGI_META(i)	NULL
1111#define NGI_META(i)	NULL
1112#define NG_FREE_META(meta)
1113#define NGI_GET_META(i,m)
1114#define	ng_copy_meta(meta) NULL
1115
1116#endif /* _NETGRAPH_NETGRAPH_H_ */
1117