xref: /freebsd/sys/netgraph/netgraph.h (revision 6af83ee0d2941d18880b6aaa2b4facd1d30c6106)
1 /*
2  * netgraph.h
3  */
4 
5 /*-
6  * Copyright (c) 1996-1999 Whistle Communications, Inc.
7  * All rights reserved.
8  *
9  * Subject to the following obligations and disclaimer of warranty, use and
10  * redistribution of this software, in source or object code forms, with or
11  * without modifications are expressly permitted by Whistle Communications;
12  * provided, however, that:
13  * 1. Any and all reproductions of the source or object code must include the
14  *    copyright notice above and the following disclaimer of warranties; and
15  * 2. No rights are granted, in any manner or form, to use Whistle
16  *    Communications, Inc. trademarks, including the mark "WHISTLE
17  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18  *    such appears in the above copyright notice or in the software.
19  *
20  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36  * OF SUCH DAMAGE.
37  *
38  * Author: Julian Elischer <julian@freebsd.org>
39  *
40  * $FreeBSD$
41  * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $
42  */
43 
44 #ifndef _NETGRAPH_NETGRAPH_H_
45 #define _NETGRAPH_NETGRAPH_H_
46 
47 #ifndef _KERNEL
48 #error "This file should not be included in user level programs"
49 #endif
50 
51 #include <sys/queue.h>
52 #include <sys/lock.h>
53 #include <sys/malloc.h>
54 #include <sys/module.h>
55 #include <sys/mutex.h>
56 /* debugging options */
57 #define NETGRAPH_DEBUG
58 #define NG_SEPARATE_MALLOC	/* make modules use their own malloc types */
59 
60 /*
61  * This defines the in-kernel binary interface version.
62  * It is possible to change this but leave the external message
63  * API the same. Each type also has it's own cookies for versioning as well.
64  * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug
65  * modules.
66  */
67 #define _NG_ABI_VERSION 10
68 #ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
69 #define NG_ABI_VERSION	(_NG_ABI_VERSION + 0x10000)
70 #else	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
71 #define NG_ABI_VERSION	_NG_ABI_VERSION
72 #endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
73 
74 
75 /*
76  * Forward references for the basic structures so we can
77  * define the typedefs and use them in the structures themselves.
78  */
79 struct ng_hook ;
80 struct ng_node ;
81 struct ng_item ;
82 typedef	struct ng_item *item_p;
83 typedef struct ng_node *node_p;
84 typedef struct ng_hook *hook_p;
85 
86 /* node method definitions */
87 typedef	int	ng_constructor_t(node_p node);
88 typedef	int	ng_close_t(node_p node);
89 typedef	int	ng_shutdown_t(node_p node);
90 typedef	int	ng_newhook_t(node_p node, hook_p hook, const char *name);
91 typedef	hook_p	ng_findhook_t(node_p node, const char *name);
92 typedef	int	ng_connect_t(hook_p hook);
93 typedef	int	ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
94 typedef	int	ng_rcvdata_t(hook_p hook, item_p item);
95 typedef	int	ng_disconnect_t(hook_p hook);
96 typedef	int	ng_rcvitem (node_p node, hook_p hook, item_p item);
97 
98 /***********************************************************************
99  ***************** Hook Structure and Methods **************************
100  ***********************************************************************
101  *
102  * Structure of a hook
103  */
104 struct ng_hook {
105 	char	hk_name[NG_HOOKSIZ];	/* what this node knows this link as */
106 	void   *hk_private;		/* node dependant ID for this hook */
107 	int	hk_flags;		/* info about this hook/link */
108 	int	hk_refs;		/* dont actually free this till 0 */
109 	struct	ng_hook *hk_peer;	/* the other end of this link */
110 	struct	ng_node *hk_node;	/* The node this hook is attached to */
111 	LIST_ENTRY(ng_hook) hk_hooks;	/* linked list of all hooks on node */
112 	ng_rcvmsg_t	*hk_rcvmsg;	/* control messages come here */
113 	ng_rcvdata_t	*hk_rcvdata;	/* data comes here */
114 #ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
115 #define HK_MAGIC 0x78573011
116 	int	hk_magic;
117 	char	*lastfile;
118 	int	lastline;
119 	SLIST_ENTRY(ng_hook)	  hk_all;		/* all existing items */
120 #endif	/* NETGRAPH_DEBUG */ /*----------------------------------------------*/
121 };
122 /* Flags for a hook */
123 #define HK_INVALID		0x0001	/* don't trust it! */
124 #define HK_QUEUE		0x0002	/* queue for later delivery */
125 #define HK_FORCE_WRITER		0x0004	/* Incoming data queued as a writer */
126 #define HK_DEAD			0x0008	/* This is the dead hook.. don't free */
127 
128 /*
129  * Public Methods for hook
130  * If you can't do it with these you probably shouldn;t be doing it.
131  */
132 void ng_unref_hook(hook_p hook); /* don't move this */
133 #define	_NG_HOOK_REF(hook)	atomic_add_int(&(hook)->hk_refs, 1)
134 #define _NG_HOOK_NAME(hook)	((hook)->hk_name)
135 #define _NG_HOOK_UNREF(hook)	ng_unref_hook(hook)
136 #define	_NG_HOOK_SET_PRIVATE(hook, val)	do {(hook)->hk_private = val;} while (0)
137 #define	_NG_HOOK_SET_RCVMSG(hook, val)	do {(hook)->hk_rcvmsg = val;} while (0)
138 #define	_NG_HOOK_SET_RCVDATA(hook, val)	do {(hook)->hk_rcvdata = val;} while (0)
139 #define	_NG_HOOK_PRIVATE(hook)	((hook)->hk_private)
140 #define _NG_HOOK_NOT_VALID(hook)	((hook)->hk_flags & HK_INVALID)
141 #define _NG_HOOK_IS_VALID(hook)	(!((hook)->hk_flags & HK_INVALID))
142 #define _NG_HOOK_NODE(hook)	((hook)->hk_node) /* only rvalue! */
143 #define _NG_HOOK_PEER(hook)	((hook)->hk_peer) /* only rvalue! */
144 #define _NG_HOOK_FORCE_WRITER(hook)				\
145 		do { hook->hk_flags |= HK_FORCE_WRITER; } while (0)
146 #define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0)
147 
148 /* Some shortcuts */
149 #define NG_PEER_NODE(hook)	NG_HOOK_NODE(NG_HOOK_PEER(hook))
150 #define NG_PEER_HOOK_NAME(hook)	NG_HOOK_NAME(NG_HOOK_PEER(hook))
151 #define NG_PEER_NODE_NAME(hook)	NG_NODE_NAME(NG_PEER_NODE(hook))
152 
153 #ifdef	NETGRAPH_DEBUG /*----------------------------------------------*/
154 #define _NN_ __FILE__,__LINE__
155 void	dumphook (hook_p hook, char *file, int line);
156 static __inline void	_chkhook(hook_p hook, char *file, int line);
157 static __inline void	_ng_hook_ref(hook_p hook, char * file, int line);
158 static __inline char *	_ng_hook_name(hook_p hook, char * file, int line);
159 static __inline void	_ng_hook_unref(hook_p hook, char * file, int line);
160 static __inline void	_ng_hook_set_private(hook_p hook,
161 				void * val, char * file, int line);
162 static __inline void	_ng_hook_set_rcvmsg(hook_p hook,
163 				ng_rcvmsg_t *val, char * file, int line);
164 static __inline void	_ng_hook_set_rcvdata(hook_p hook,
165 				ng_rcvdata_t *val, char * file, int line);
166 static __inline void *	_ng_hook_private(hook_p hook, char * file, int line);
167 static __inline int	_ng_hook_not_valid(hook_p hook, char * file, int line);
168 static __inline int	_ng_hook_is_valid(hook_p hook, char * file, int line);
169 static __inline node_p	_ng_hook_node(hook_p hook, char * file, int line);
170 static __inline hook_p	_ng_hook_peer(hook_p hook, char * file, int line);
171 static __inline void	_ng_hook_force_writer(hook_p hook, char * file,
172 					int line);
173 static __inline void	_ng_hook_force_queue(hook_p hook, char * file, int line);
174 
175 static void __inline
176 _chkhook(hook_p hook, char *file, int line)
177 {
178 	if (hook->hk_magic != HK_MAGIC) {
179 		printf("Accessing freed hook ");
180 		dumphook(hook, file, line);
181 	}
182 	hook->lastline = line;
183 	hook->lastfile = file;
184 }
185 
186 static __inline void
187 _ng_hook_ref(hook_p hook, char * file, int line)
188 {
189 	_chkhook(hook, file, line);
190 	_NG_HOOK_REF(hook);
191 }
192 
193 static __inline char *
194 _ng_hook_name(hook_p hook, char * file, int line)
195 {
196 	_chkhook(hook, file, line);
197 	return (_NG_HOOK_NAME(hook));
198 }
199 
200 static __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 
207 static __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 
214 static __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 
221 static __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 
228 static __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 
235 static __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 
242 static __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 
249 static __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 
256 static __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 
263 static __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 
270 static __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  */
319 struct 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 
327 struct 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  */
369 int	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  */
392 typedef	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 /*----------------------------------------------*/
406 void	dumpnode(node_p node, char *file, int line);
407 static void __inline _chknode(node_p node, char *file, int line);
408 static __inline char * _ng_node_name(node_p node, char *file, int line);
409 static __inline int _ng_node_has_name(node_p node, char *file, int line);
410 static __inline ng_ID_t _ng_node_id(node_p node, char *file, int line);
411 void ng_ref_node(node_p node);
412 static __inline void _ng_node_ref(node_p node, char *file, int line);
413 static __inline int _ng_node_unref(node_p node, char *file, int line);
414 static __inline void _ng_node_set_private(node_p node, void * val,
415 							char *file, int line);
416 static __inline void * _ng_node_private(node_p node, char *file, int line);
417 static __inline int _ng_node_is_valid(node_p node, char *file, int line);
418 static __inline int _ng_node_not_valid(node_p node, char *file, int line);
419 static __inline int _ng_node_numhooks(node_p node, char *file, int line);
420 static __inline void _ng_node_force_writer(node_p node, char *file, int line);
421 static __inline hook_p _ng_node_foreach_hook(node_p node,
422 			ng_fn_eachhook *fn, void *arg, char *file, int line);
423 static __inline void _ng_node_revive(node_p node, char *file, int line);
424 
425 static 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 
436 static __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 
443 static __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 
450 static __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 
457 static __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 
465 static __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 
472 static __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 
479 static __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 
486 static __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 
493 static __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 
500 static __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 
507 static __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 
514 static __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 
521 static __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 
528 static __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  */
580 typedef	void	ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2);
581 struct 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 /*----------------------------------------------*/
653 void				dumpitem(item_p item, char *file, int line);
654 static __inline void		_ngi_check(item_p item, char *file, int line) ;
655 static __inline struct mbuf **	_ngi_m(item_p item, char *file, int line) ;
656 static __inline ng_ID_t *	_ngi_retaddr(item_p item, char *file, int line);
657 static __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ;
658 static __inline ng_item_fn **	_ngi_fn(item_p item, char *file, int line) ;
659 static __inline void **		_ngi_arg1(item_p item, char *file, int line) ;
660 static __inline int *		_ngi_arg2(item_p item, char *file, int line) ;
661 static __inline node_p		_ngi_node(item_p item, char *file, int line);
662 static __inline hook_p		_ngi_hook(item_p item, char *file, int line);
663 
664 static __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 
675 static __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 
682 static __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 
689 static __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 
696 static __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 
703 static __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 
710 static __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 
717 static __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 
724 static __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 				(error) = EINVAL;			\
952 			}						\
953 		} else {						\
954 			NG_FREE_ITEM(item);				\
955 		}							\
956 		(item) = NULL;						\
957 	} while (0)
958 
959 
960 /***********************************************************************
961  ******** Structures Definitions and Macros for defining a node  *******
962  ***********************************************************************
963  *
964  * Here we define the structures needed to actually define a new node
965  * type.
966  */
967 
968 /*
969  * Command list -- each node type specifies the command that it knows
970  * how to convert between ASCII and binary using an array of these.
971  * The last element in the array must be a terminator with cookie=0.
972  */
973 
974 struct ng_cmdlist {
975 	u_int32_t			cookie;		/* command typecookie */
976 	int				cmd;		/* command number */
977 	const char			*name;		/* command name */
978 	const struct ng_parse_type	*mesgType;	/* args if !NGF_RESP */
979 	const struct ng_parse_type	*respType;	/* args if NGF_RESP */
980 };
981 
982 /*
983  * Structure of a node type
984  * If data is sent to the "rcvdata()" entrypoint then the system
985  * may decide to defer it until later by queing it with the normal netgraph
986  * input queuing system.  This is decidde by the HK_QUEUE flag being set in
987  * the flags word of the peer (receiving) hook. The dequeuing mechanism will
988  * ensure it is not requeued again.
989  * Note the input queueing system is to allow modules
990  * to 'release the stack' or to pass data across spl layers.
991  * The data will be redelivered as soon as the NETISR code runs
992  * which may be almost immediatly.  A node may also do it's own queueing
993  * for other reasons (e.g. device output queuing).
994  */
995 struct ng_type {
996 
997 	u_int32_t	version; 	/* must equal NG_API_VERSION */
998 	const char	*name;		/* Unique type name */
999 	modeventhand_t	mod_event;	/* Module event handler (optional) */
1000 	ng_constructor_t *constructor;	/* Node constructor */
1001 	ng_rcvmsg_t	*rcvmsg;	/* control messages come here */
1002 	ng_close_t	*close;		/* warn about forthcoming shutdown */
1003 	ng_shutdown_t	*shutdown;	/* reset, and free resources */
1004 	ng_newhook_t	*newhook;	/* first notification of new hook */
1005 	ng_findhook_t	*findhook;	/* only if you have lots of hooks */
1006 	ng_connect_t	*connect;	/* final notification of new hook */
1007 	ng_rcvdata_t	*rcvdata;	/* data comes here */
1008 	ng_disconnect_t	*disconnect;	/* notify on disconnect */
1009 
1010 	const struct	ng_cmdlist *cmdlist;	/* commands we can convert */
1011 
1012 	/* R/W data private to the base netgraph code DON'T TOUCH! */
1013 	LIST_ENTRY(ng_type) types;		/* linked list of all types */
1014 	int		    refs;		/* number of instances */
1015 };
1016 
1017 /*
1018  * Use the NETGRAPH_INIT() macro to link a node type into the
1019  * netgraph system. This works for types compiled into the kernel
1020  * as well as KLD modules. The first argument should be the type
1021  * name (eg, echo) and the second a pointer to the type struct.
1022  *
1023  * If a different link time is desired, e.g., a device driver that
1024  * needs to install its netgraph type before probing, use the
1025  * NETGRAPH_INIT_ORDERED() macro instead. Deivce drivers probably
1026  * want to use SI_SUB_DRIVERS instead of SI_SUB_PSEUDO.
1027  */
1028 
1029 #define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order)	\
1030 static moduledata_t ng_##typename##_mod = {				\
1031 	"ng_" #typename,						\
1032 	ng_mod_event,							\
1033 	(typestructp)							\
1034 };									\
1035 DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order);		\
1036 MODULE_DEPEND(ng_##typename, netgraph,	NG_ABI_VERSION,			\
1037 					NG_ABI_VERSION,			\
1038 					NG_ABI_VERSION)
1039 
1040 #define NETGRAPH_INIT(tn, tp)						\
1041 	NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY)
1042 
1043 /* Special malloc() type for netgraph structs and ctrl messages */
1044 /* Only these two types should be visible to nodes */
1045 MALLOC_DECLARE(M_NETGRAPH);
1046 MALLOC_DECLARE(M_NETGRAPH_MSG);
1047 
1048 /* declare the base of the netgraph sysclt hierarchy */
1049 /* but only if this file cares about sysctls */
1050 #ifdef	SYSCTL_DECL
1051 SYSCTL_DECL(_net_graph);
1052 #endif
1053 
1054 /*
1055  * Methods that the nodes can use.
1056  * Many of these methods should usually NOT be used directly but via
1057  * Macros above.
1058  */
1059 int	ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr);
1060 int	ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
1061 int	ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr);
1062 int	ng_bypass(hook_p hook1, hook_p hook2);
1063 hook_p	ng_findhook(node_p node, const char *name);
1064 struct	ng_type *ng_findtype(const char *type);
1065 int	ng_make_node_common(struct ng_type *typep, node_p *nodep);
1066 int	ng_name_node(node_p node, const char *name);
1067 int	ng_newtype(struct ng_type *tp);
1068 ng_ID_t ng_node2ID(node_p node);
1069 item_p	ng_package_data(struct mbuf *m, void *dummy);
1070 item_p	ng_package_msg(struct ng_mesg *msg);
1071 item_p	ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg);
1072 void	ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr);
1073 int	ng_rmhook_self(hook_p hook);	/* if a node wants to kill a hook */
1074 int	ng_rmnode_self(node_p here);	/* if a node wants to suicide */
1075 int	ng_rmtype(struct ng_type *tp);
1076 int	ng_snd_item(item_p item, int queue);
1077 int 	ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn,
1078 	void *arg1, int arg2);
1079 int	ng_uncallout(struct callout *c, node_p node);
1080 int	ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
1081 	    ng_item_fn *fn, void * arg1, int arg2);
1082 #define	ng_callout_init(c)	callout_init(c, CALLOUT_MPSAFE)
1083 
1084 /*
1085  * prototypes the user should DEFINITELY not use directly
1086  */
1087 void	ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */
1088 int	ng_mod_event(module_t mod, int what, void *arg);
1089 
1090 /*
1091  * Tag definitions and constants
1092  */
1093 
1094 #define	NG_TAG_PRIO	1
1095 
1096 struct ng_tag_prio {
1097 	struct m_tag	tag;
1098 	char	priority;
1099 	char	discardability;
1100 };
1101 
1102 #define	NG_PRIO_CUTOFF		32
1103 #define	NG_PRIO_LINKSTATE	64
1104 
1105 /* Macros and declarations to keep compatibility with metadata, which
1106  * is obsoleted now. To be deleted.
1107  */
1108 typedef void *meta_p;
1109 #define _NGI_META(i)	NULL
1110 #define NGI_META(i)	NULL
1111 #define NG_FREE_META(meta)
1112 #define NGI_GET_META(i,m)
1113 #define	ng_copy_meta(meta) NULL
1114 
1115 #endif /* _NETGRAPH_NETGRAPH_H_ */
1116