Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netgraph/netgraph.h
34372 views
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 <[email protected]>
39
* $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $
40
*/
41
42
#ifndef _NETGRAPH_NETGRAPH_H_
43
#define _NETGRAPH_NETGRAPH_H_
44
45
#ifndef _KERNEL
46
#error "This file should not be included in user level programs"
47
#endif
48
49
#include <sys/queue.h>
50
#include <sys/lock.h>
51
#include <sys/malloc.h>
52
#include <sys/module.h>
53
#include <sys/mutex.h>
54
#include <sys/refcount.h>
55
56
#ifdef HAVE_KERNEL_OPTION_HEADERS
57
#include "opt_netgraph.h"
58
#include "opt_kdb.h"
59
#endif
60
61
/* debugging options */
62
#define NG_SEPARATE_MALLOC /* make modules use their own malloc types */
63
64
/*
65
* This defines the in-kernel binary interface version.
66
* It is possible to change this but leave the external message
67
* API the same. Each type also has it's own cookies for versioning as well.
68
* Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug
69
* modules.
70
*/
71
#define _NG_ABI_VERSION 12
72
73
#ifdef NETGRAPH_DEBUG
74
#define _NG_ABI_PREFIX1 0x10000
75
#else
76
#define _NG_ABI_PREFIX1 0
77
#endif
78
79
#ifdef INVARIANTS
80
#define _NG_ABI_PREFIX2 0x20000
81
#else
82
#define _NG_ABI_PREFIX2 0
83
#endif
84
85
#define NG_ABI_VERSION (_NG_ABI_PREFIX1 + _NG_ABI_PREFIX2 + _NG_ABI_VERSION)
86
87
/*
88
* Forward references for the basic structures so we can
89
* define the typedefs and use them in the structures themselves.
90
*/
91
struct ng_hook ;
92
struct ng_node ;
93
struct ng_item ;
94
typedef struct ng_item *item_p;
95
typedef struct ng_node *node_p;
96
typedef struct ng_hook *hook_p;
97
typedef struct ng_item const *item_cp;
98
typedef struct ng_hook const *hook_cp;
99
#ifdef NETGRAPH_DEBUG
100
typedef struct ng_node *node_cp; /* annotated during debug */
101
#else /* NETGRAPH_DEBUG */
102
typedef struct ng_node const *node_cp;
103
#endif /* NETGRAPH_DEBUG */
104
105
/* node method definitions */
106
typedef int ng_constructor_t(node_p node);
107
typedef int ng_close_t(node_p node);
108
typedef int ng_shutdown_t(node_p node);
109
typedef int ng_newhook_t(node_p node, hook_p hook, const char *name);
110
typedef hook_p ng_findhook_t(node_p node, const char *name);
111
typedef int ng_connect_t(hook_p hook);
112
typedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook);
113
typedef int ng_rcvdata_t(hook_p hook, item_p item);
114
typedef int ng_disconnect_t(hook_p hook);
115
typedef int ng_rcvitem (node_p node, hook_p hook, item_p item);
116
117
/***********************************************************************
118
***************** Hook Structure and Methods **************************
119
***********************************************************************
120
*
121
* Structure of a hook
122
*/
123
struct ng_hook {
124
char hk_name[NG_HOOKSIZ]; /* what this node knows this link as */
125
void *hk_private; /* node dependent ID for this hook */
126
int hk_flags; /* info about this hook/link */
127
int hk_type; /* tbd: hook data link type */
128
struct ng_hook *hk_peer; /* the other end of this link */
129
struct ng_node *hk_node; /* The node this hook is attached to */
130
LIST_ENTRY(ng_hook) hk_hooks; /* linked list of all hooks on node */
131
ng_rcvmsg_t *hk_rcvmsg; /* control messages come here */
132
ng_rcvdata_t *hk_rcvdata; /* data comes here */
133
int hk_refs; /* dont actually free this till 0 */
134
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
135
#define HK_MAGIC 0x78573011
136
int hk_magic;
137
char *lastfile;
138
int lastline;
139
SLIST_ENTRY(ng_hook) hk_all; /* all existing items */
140
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
141
};
142
/* Flags for a hook */
143
#define HK_INVALID 0x0001 /* don't trust it! */
144
#define HK_QUEUE 0x0002 /* queue for later delivery */
145
#define HK_FORCE_WRITER 0x0004 /* Incoming data queued as a writer */
146
#define HK_DEAD 0x0008 /* This is the dead hook.. don't free */
147
#define HK_HI_STACK 0x0010 /* Hook has hi stack usage */
148
#define HK_TO_INBOUND 0x0020 /* Hook on ntw. stack inbound path. */
149
150
/*
151
* Public Methods for hook
152
* If you can't do it with these you probably shouldn;t be doing it.
153
*/
154
void ng_unref_hook(hook_p hook); /* don't move this */
155
#define _NG_HOOK_REF(hook) refcount_acquire(&(hook)->hk_refs)
156
#define _NG_HOOK_NAME(hook) ((hook)->hk_name)
157
#define _NG_HOOK_UNREF(hook) ng_unref_hook(hook)
158
#define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0)
159
#define _NG_HOOK_SET_RCVMSG(hook, val) do {(hook)->hk_rcvmsg = val;} while (0)
160
#define _NG_HOOK_SET_RCVDATA(hook, val) do {(hook)->hk_rcvdata = val;} while (0)
161
#define _NG_HOOK_PRIVATE(hook) ((hook)->hk_private)
162
#define _NG_HOOK_NOT_VALID(hook) ((hook)->hk_flags & HK_INVALID)
163
#define _NG_HOOK_IS_VALID(hook) (!((hook)->hk_flags & HK_INVALID))
164
#define _NG_HOOK_NODE(hook) ((hook)->hk_node) /* only rvalue! */
165
#define _NG_HOOK_PEER(hook) ((hook)->hk_peer) /* only rvalue! */
166
#define _NG_HOOK_FORCE_WRITER(hook) \
167
do { hook->hk_flags |= HK_FORCE_WRITER; } while (0)
168
#define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0)
169
#define _NG_HOOK_SET_TO_INBOUND(hook) \
170
do { hook->hk_flags |= HK_TO_INBOUND; } while (0)
171
#define _NG_HOOK_HI_STACK(hook) do { hook->hk_flags |= HK_HI_STACK; } while (0)
172
173
/* Some shortcuts */
174
#define NG_PEER_NODE(hook) NG_HOOK_NODE(NG_HOOK_PEER(hook))
175
#define NG_PEER_HOOK_NAME(hook) NG_HOOK_NAME(NG_HOOK_PEER(hook))
176
#define NG_PEER_NODE_NAME(hook) NG_NODE_NAME(NG_PEER_NODE(hook))
177
178
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
179
#define _NN_ __FILE__,__LINE__
180
void dumphook (hook_p hook, char *file, int line);
181
static __inline void _chkhook(hook_p hook, char *file, int line);
182
static __inline void _ng_hook_ref(hook_p hook, char * file, int line);
183
static __inline char * _ng_hook_name(hook_p hook, char * file, int line);
184
static __inline void _ng_hook_unref(hook_p hook, char * file, int line);
185
static __inline void _ng_hook_set_private(hook_p hook,
186
void * val, char * file, int line);
187
static __inline void _ng_hook_set_rcvmsg(hook_p hook,
188
ng_rcvmsg_t *val, char * file, int line);
189
static __inline void _ng_hook_set_rcvdata(hook_p hook,
190
ng_rcvdata_t *val, char * file, int line);
191
static __inline void * _ng_hook_private(hook_p hook, char * file, int line);
192
static __inline int _ng_hook_not_valid(hook_p hook, char * file, int line);
193
static __inline int _ng_hook_is_valid(hook_p hook, char * file, int line);
194
static __inline node_p _ng_hook_node(hook_p hook, char * file, int line);
195
static __inline hook_p _ng_hook_peer(hook_p hook, char * file, int line);
196
static __inline void _ng_hook_force_writer(hook_p hook, char * file,
197
int line);
198
static __inline void _ng_hook_force_queue(hook_p hook, char * file,
199
int line);
200
static __inline void _ng_hook_set_to_inbound(hook_p hook, char * file,
201
int line);
202
203
static __inline void
204
_chkhook(hook_p hook, char *file, int line)
205
{
206
if (hook->hk_magic != HK_MAGIC) {
207
printf("Accessing freed ");
208
dumphook(hook, file, line);
209
}
210
hook->lastline = line;
211
hook->lastfile = file;
212
}
213
214
static __inline void
215
_ng_hook_ref(hook_p hook, char * file, int line)
216
{
217
_chkhook(hook, file, line);
218
_NG_HOOK_REF(hook);
219
}
220
221
static __inline char *
222
_ng_hook_name(hook_p hook, char * file, int line)
223
{
224
_chkhook(hook, file, line);
225
return (_NG_HOOK_NAME(hook));
226
}
227
228
static __inline void
229
_ng_hook_unref(hook_p hook, char * file, int line)
230
{
231
_chkhook(hook, file, line);
232
_NG_HOOK_UNREF(hook);
233
}
234
235
static __inline void
236
_ng_hook_set_private(hook_p hook, void *val, char * file, int line)
237
{
238
_chkhook(hook, file, line);
239
_NG_HOOK_SET_PRIVATE(hook, val);
240
}
241
242
static __inline void
243
_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line)
244
{
245
_chkhook(hook, file, line);
246
_NG_HOOK_SET_RCVMSG(hook, val);
247
}
248
249
static __inline void
250
_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line)
251
{
252
_chkhook(hook, file, line);
253
_NG_HOOK_SET_RCVDATA(hook, val);
254
}
255
256
static __inline void *
257
_ng_hook_private(hook_p hook, char * file, int line)
258
{
259
_chkhook(hook, file, line);
260
return (_NG_HOOK_PRIVATE(hook));
261
}
262
263
static __inline int
264
_ng_hook_not_valid(hook_p hook, char * file, int line)
265
{
266
_chkhook(hook, file, line);
267
return (_NG_HOOK_NOT_VALID(hook));
268
}
269
270
static __inline int
271
_ng_hook_is_valid(hook_p hook, char * file, int line)
272
{
273
_chkhook(hook, file, line);
274
return (_NG_HOOK_IS_VALID(hook));
275
}
276
277
static __inline node_p
278
_ng_hook_node(hook_p hook, char * file, int line)
279
{
280
_chkhook(hook, file, line);
281
return (_NG_HOOK_NODE(hook));
282
}
283
284
static __inline hook_p
285
_ng_hook_peer(hook_p hook, char * file, int line)
286
{
287
_chkhook(hook, file, line);
288
return (_NG_HOOK_PEER(hook));
289
}
290
291
static __inline void
292
_ng_hook_force_writer(hook_p hook, char * file, int line)
293
{
294
_chkhook(hook, file, line);
295
_NG_HOOK_FORCE_WRITER(hook);
296
}
297
298
static __inline void
299
_ng_hook_force_queue(hook_p hook, char * file, int line)
300
{
301
_chkhook(hook, file, line);
302
_NG_HOOK_FORCE_QUEUE(hook);
303
}
304
305
static __inline void
306
_ng_hook_set_to_inbound(hook_p hook, char * file, int line)
307
{
308
_chkhook(hook, file, line);
309
_NG_HOOK_SET_TO_INBOUND(hook);
310
}
311
312
static __inline void
313
_ng_hook_hi_stack(hook_p hook, char * file, int line)
314
{
315
_chkhook(hook, file, line);
316
_NG_HOOK_HI_STACK(hook);
317
}
318
319
#define NG_HOOK_REF(hook) _ng_hook_ref(hook, _NN_)
320
#define NG_HOOK_NAME(hook) _ng_hook_name(hook, _NN_)
321
#define NG_HOOK_UNREF(hook) _ng_hook_unref(hook, _NN_)
322
#define NG_HOOK_SET_PRIVATE(hook, val) _ng_hook_set_private(hook, val, _NN_)
323
#define NG_HOOK_SET_RCVMSG(hook, val) _ng_hook_set_rcvmsg(hook, val, _NN_)
324
#define NG_HOOK_SET_RCVDATA(hook, val) _ng_hook_set_rcvdata(hook, val, _NN_)
325
#define NG_HOOK_PRIVATE(hook) _ng_hook_private(hook, _NN_)
326
#define NG_HOOK_NOT_VALID(hook) _ng_hook_not_valid(hook, _NN_)
327
#define NG_HOOK_IS_VALID(hook) _ng_hook_is_valid(hook, _NN_)
328
#define NG_HOOK_NODE(hook) _ng_hook_node(hook, _NN_)
329
#define NG_HOOK_PEER(hook) _ng_hook_peer(hook, _NN_)
330
#define NG_HOOK_FORCE_WRITER(hook) _ng_hook_force_writer(hook, _NN_)
331
#define NG_HOOK_FORCE_QUEUE(hook) _ng_hook_force_queue(hook, _NN_)
332
#define NG_HOOK_SET_TO_INBOUND(hook) _ng_hook_set_to_inbound(hook, _NN_)
333
#define NG_HOOK_HI_STACK(hook) _ng_hook_hi_stack(hook, _NN_)
334
335
#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
336
337
#define NG_HOOK_REF(hook) _NG_HOOK_REF(hook)
338
#define NG_HOOK_NAME(hook) _NG_HOOK_NAME(hook)
339
#define NG_HOOK_UNREF(hook) _NG_HOOK_UNREF(hook)
340
#define NG_HOOK_SET_PRIVATE(hook, val) _NG_HOOK_SET_PRIVATE(hook, val)
341
#define NG_HOOK_SET_RCVMSG(hook, val) _NG_HOOK_SET_RCVMSG(hook, val)
342
#define NG_HOOK_SET_RCVDATA(hook, val) _NG_HOOK_SET_RCVDATA(hook, val)
343
#define NG_HOOK_PRIVATE(hook) _NG_HOOK_PRIVATE(hook)
344
#define NG_HOOK_NOT_VALID(hook) _NG_HOOK_NOT_VALID(hook)
345
#define NG_HOOK_IS_VALID(hook) _NG_HOOK_IS_VALID(hook)
346
#define NG_HOOK_NODE(hook) _NG_HOOK_NODE(hook)
347
#define NG_HOOK_PEER(hook) _NG_HOOK_PEER(hook)
348
#define NG_HOOK_FORCE_WRITER(hook) _NG_HOOK_FORCE_WRITER(hook)
349
#define NG_HOOK_FORCE_QUEUE(hook) _NG_HOOK_FORCE_QUEUE(hook)
350
#define NG_HOOK_SET_TO_INBOUND(hook) _NG_HOOK_SET_TO_INBOUND(hook)
351
#define NG_HOOK_HI_STACK(hook) _NG_HOOK_HI_STACK(hook)
352
353
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
354
355
/***********************************************************************
356
***************** Node Structure and Methods **************************
357
***********************************************************************
358
* Structure of a node
359
* including the eembedded queue structure.
360
*
361
* The structure for queueing Netgraph request items
362
* embedded in the node structure
363
*/
364
struct ng_queue {
365
u_int q_flags; /* Current r/w/q lock flags */
366
u_int q_flags2; /* Other queue flags */
367
struct mtx q_mtx;
368
STAILQ_ENTRY(ng_node) q_work; /* nodes with work to do */
369
STAILQ_HEAD(, ng_item) queue; /* actually items queue */
370
};
371
372
struct ng_node {
373
char nd_name[NG_NODESIZ]; /* optional globally unique name */
374
struct ng_type *nd_type; /* the installed 'type' */
375
int nd_flags; /* see below for bit definitions */
376
int nd_numhooks; /* number of hooks */
377
void *nd_private; /* node type dependent node ID */
378
ng_ID_t nd_ID; /* Unique per node */
379
LIST_HEAD(hooks, ng_hook) nd_hooks; /* linked list of node hooks */
380
LIST_ENTRY(ng_node) nd_nodes; /* name hash collision list */
381
LIST_ENTRY(ng_node) nd_idnodes; /* ID hash collision list */
382
struct ng_queue nd_input_queue; /* input queue for locking */
383
int nd_refs; /* # of references to this node */
384
struct vnet *nd_vnet; /* network stack instance */
385
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
386
#define ND_MAGIC 0x59264837
387
int nd_magic;
388
char *lastfile;
389
int lastline;
390
SLIST_ENTRY(ng_node) nd_all; /* all existing nodes */
391
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
392
};
393
394
/* Flags for a node */
395
#define NGF_INVALID 0x00000001 /* free when refs go to 0 */
396
#define NG_INVALID NGF_INVALID /* compat for old code */
397
#define NGF_FORCE_WRITER 0x00000004 /* Never multithread this node */
398
#define NG_FORCE_WRITER NGF_FORCE_WRITER /* compat for old code */
399
#define NGF_CLOSING 0x00000008 /* ng_rmnode() at work */
400
#define NG_CLOSING NGF_CLOSING /* compat for old code */
401
#define NGF_REALLY_DIE 0x00000010 /* "persistent" node is unloading */
402
#define NG_REALLY_DIE NGF_REALLY_DIE /* compat for old code */
403
#define NGF_HI_STACK 0x00000020 /* node has hi stack usage */
404
#define NGF_TYPE1 0x10000000 /* reserved for type specific storage */
405
#define NGF_TYPE2 0x20000000 /* reserved for type specific storage */
406
#define NGF_TYPE3 0x40000000 /* reserved for type specific storage */
407
#define NGF_TYPE4 0x80000000 /* reserved for type specific storage */
408
409
/*
410
* Public methods for nodes.
411
* If you can't do it with these you probably shouldn't be doing it.
412
*/
413
void ng_unref_node(node_p node); /* don't move this */
414
#define _NG_NODE_NAME(node) ((node)->nd_name + 0)
415
#define _NG_NODE_HAS_NAME(node) ((node)->nd_name[0] + 0)
416
#define _NG_NODE_ID(node) ((node)->nd_ID + 0)
417
#define _NG_NODE_REF(node) refcount_acquire(&(node)->nd_refs)
418
#define _NG_NODE_UNREF(node) ng_unref_node(node)
419
#define _NG_NODE_SET_PRIVATE(node, val) do {(node)->nd_private = val;} while (0)
420
#define _NG_NODE_PRIVATE(node) ((node)->nd_private)
421
#define _NG_NODE_IS_VALID(node) (!((node)->nd_flags & NGF_INVALID))
422
#define _NG_NODE_NOT_VALID(node) ((node)->nd_flags & NGF_INVALID)
423
#define _NG_NODE_NUMHOOKS(node) ((node)->nd_numhooks + 0) /* rvalue */
424
#define _NG_NODE_FORCE_WRITER(node) \
425
do{ node->nd_flags |= NGF_FORCE_WRITER; }while (0)
426
#define _NG_NODE_HI_STACK(node) \
427
do{ node->nd_flags |= NGF_HI_STACK; }while (0)
428
#define _NG_NODE_REALLY_DIE(node) \
429
do{ node->nd_flags |= (NGF_REALLY_DIE|NGF_INVALID); }while (0)
430
#define _NG_NODE_REVIVE(node) \
431
do { node->nd_flags &= ~NGF_INVALID; } while (0)
432
/*
433
* The hook iterator.
434
* This macro will call a function of type ng_fn_eachhook for each
435
* hook attached to the node. If the function returns 0, then the
436
* iterator will stop and return a pointer to the hook that returned 0.
437
*/
438
typedef int ng_fn_eachhook(hook_p hook, void* arg);
439
#define _NG_NODE_FOREACH_HOOK(node, fn, arg) \
440
do { \
441
hook_p _hook; \
442
LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) { \
443
if ((fn)(_hook, arg) == 0) { \
444
break; \
445
} \
446
} \
447
} while (0)
448
449
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
450
void dumpnode(node_p node, char *file, int line);
451
static __inline void _chknode(node_p node, char *file, int line);
452
static __inline char * _ng_node_name(node_p node, char *file, int line);
453
static __inline int _ng_node_has_name(node_p node, char *file, int line);
454
static __inline ng_ID_t _ng_node_id(node_p node, char *file, int line);
455
static __inline void _ng_node_ref(node_p node, char *file, int line);
456
static __inline void _ng_node_unref(node_p node, char *file, int line);
457
static __inline void _ng_node_set_private(node_p node, void * val,
458
char *file, int line);
459
static __inline void * _ng_node_private(node_p node, char *file, int line);
460
static __inline int _ng_node_is_valid(node_p node, char *file, int line);
461
static __inline int _ng_node_not_valid(node_p node, char *file, int line);
462
static __inline int _ng_node_numhooks(node_p node, char *file, int line);
463
static __inline void _ng_node_force_writer(node_p node, char *file, int line);
464
static __inline void _ng_node_foreach_hook(node_p node,
465
ng_fn_eachhook *fn, void *arg, char *file, int line);
466
static __inline void _ng_node_revive(node_p node, char *file, int line);
467
468
static __inline void
469
_chknode(node_p node, char *file, int line)
470
{
471
if (node->nd_magic != ND_MAGIC) {
472
printf("Accessing freed ");
473
dumpnode(node, file, line);
474
}
475
node->lastline = line;
476
node->lastfile = file;
477
}
478
479
static __inline char *
480
_ng_node_name(node_p node, char *file, int line)
481
{
482
_chknode(node, file, line);
483
return(_NG_NODE_NAME(node));
484
}
485
486
static __inline int
487
_ng_node_has_name(node_p node, char *file, int line)
488
{
489
_chknode(node, file, line);
490
return(_NG_NODE_HAS_NAME(node));
491
}
492
493
static __inline ng_ID_t
494
_ng_node_id(node_p node, char *file, int line)
495
{
496
_chknode(node, file, line);
497
return(_NG_NODE_ID(node));
498
}
499
500
static __inline void
501
_ng_node_ref(node_p node, char *file, int line)
502
{
503
_chknode(node, file, line);
504
_NG_NODE_REF(node);
505
}
506
507
static __inline void
508
_ng_node_unref(node_p node, char *file, int line)
509
{
510
_chknode(node, file, line);
511
_NG_NODE_UNREF(node);
512
}
513
514
static __inline void
515
_ng_node_set_private(node_p node, void * val, char *file, int line)
516
{
517
_chknode(node, file, line);
518
_NG_NODE_SET_PRIVATE(node, val);
519
}
520
521
static __inline void *
522
_ng_node_private(node_p node, char *file, int line)
523
{
524
_chknode(node, file, line);
525
return (_NG_NODE_PRIVATE(node));
526
}
527
528
static __inline int
529
_ng_node_is_valid(node_p node, char *file, int line)
530
{
531
_chknode(node, file, line);
532
return(_NG_NODE_IS_VALID(node));
533
}
534
535
static __inline int
536
_ng_node_not_valid(node_p node, char *file, int line)
537
{
538
_chknode(node, file, line);
539
return(_NG_NODE_NOT_VALID(node));
540
}
541
542
static __inline int
543
_ng_node_numhooks(node_p node, char *file, int line)
544
{
545
_chknode(node, file, line);
546
return(_NG_NODE_NUMHOOKS(node));
547
}
548
549
static __inline void
550
_ng_node_force_writer(node_p node, char *file, int line)
551
{
552
_chknode(node, file, line);
553
_NG_NODE_FORCE_WRITER(node);
554
}
555
556
static __inline void
557
_ng_node_hi_stack(node_p node, char *file, int line)
558
{
559
_chknode(node, file, line);
560
_NG_NODE_HI_STACK(node);
561
}
562
563
static __inline void
564
_ng_node_really_die(node_p node, char *file, int line)
565
{
566
_chknode(node, file, line);
567
_NG_NODE_REALLY_DIE(node);
568
}
569
570
static __inline void
571
_ng_node_revive(node_p node, char *file, int line)
572
{
573
_chknode(node, file, line);
574
_NG_NODE_REVIVE(node);
575
}
576
577
static __inline void
578
_ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg,
579
char *file, int line)
580
{
581
_chknode(node, file, line);
582
_NG_NODE_FOREACH_HOOK(node, fn, arg);
583
}
584
585
#define NG_NODE_NAME(node) _ng_node_name(node, _NN_)
586
#define NG_NODE_HAS_NAME(node) _ng_node_has_name(node, _NN_)
587
#define NG_NODE_ID(node) _ng_node_id(node, _NN_)
588
#define NG_NODE_REF(node) _ng_node_ref(node, _NN_)
589
#define NG_NODE_UNREF(node) _ng_node_unref(node, _NN_)
590
#define NG_NODE_SET_PRIVATE(node, val) _ng_node_set_private(node, val, _NN_)
591
#define NG_NODE_PRIVATE(node) _ng_node_private(node, _NN_)
592
#define NG_NODE_IS_VALID(node) _ng_node_is_valid(node, _NN_)
593
#define NG_NODE_NOT_VALID(node) _ng_node_not_valid(node, _NN_)
594
#define NG_NODE_FORCE_WRITER(node) _ng_node_force_writer(node, _NN_)
595
#define NG_NODE_HI_STACK(node) _ng_node_hi_stack(node, _NN_)
596
#define NG_NODE_REALLY_DIE(node) _ng_node_really_die(node, _NN_)
597
#define NG_NODE_NUMHOOKS(node) _ng_node_numhooks(node, _NN_)
598
#define NG_NODE_REVIVE(node) _ng_node_revive(node, _NN_)
599
#define NG_NODE_FOREACH_HOOK(node, fn, arg) \
600
_ng_node_foreach_hook(node, fn, (void *)arg, _NN_)
601
602
#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
603
604
#define NG_NODE_NAME(node) _NG_NODE_NAME(node)
605
#define NG_NODE_HAS_NAME(node) _NG_NODE_HAS_NAME(node)
606
#define NG_NODE_ID(node) _NG_NODE_ID(node)
607
#define NG_NODE_REF(node) _NG_NODE_REF(node)
608
#define NG_NODE_UNREF(node) _NG_NODE_UNREF(node)
609
#define NG_NODE_SET_PRIVATE(node, val) _NG_NODE_SET_PRIVATE(node, val)
610
#define NG_NODE_PRIVATE(node) _NG_NODE_PRIVATE(node)
611
#define NG_NODE_IS_VALID(node) _NG_NODE_IS_VALID(node)
612
#define NG_NODE_NOT_VALID(node) _NG_NODE_NOT_VALID(node)
613
#define NG_NODE_FORCE_WRITER(node) _NG_NODE_FORCE_WRITER(node)
614
#define NG_NODE_HI_STACK(node) _NG_NODE_HI_STACK(node)
615
#define NG_NODE_REALLY_DIE(node) _NG_NODE_REALLY_DIE(node)
616
#define NG_NODE_NUMHOOKS(node) _NG_NODE_NUMHOOKS(node)
617
#define NG_NODE_REVIVE(node) _NG_NODE_REVIVE(node)
618
#define NG_NODE_FOREACH_HOOK(node, fn, arg) \
619
_NG_NODE_FOREACH_HOOK(node, fn, arg)
620
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
621
622
/***********************************************************************
623
************* Node Queue and Item Structures and Methods **************
624
***********************************************************************
625
*
626
*/
627
typedef void ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2);
628
typedef int ng_item_fn2(node_p node, struct ng_item *item, hook_p hook);
629
typedef void ng_apply_t(void *context, int error);
630
struct ng_apply_info {
631
ng_apply_t *apply;
632
void *context;
633
int refs;
634
int error;
635
};
636
struct ng_item {
637
u_long el_flags;
638
STAILQ_ENTRY(ng_item) el_next;
639
node_p el_dest; /* The node it will be applied against (or NULL) */
640
hook_p el_hook; /* Entering hook. Optional in Control messages */
641
union {
642
struct mbuf *da_m;
643
struct {
644
struct ng_mesg *msg_msg;
645
ng_ID_t msg_retaddr;
646
} msg;
647
struct {
648
union {
649
ng_item_fn *fn_fn;
650
ng_item_fn2 *fn_fn2;
651
} fn_fn;
652
void *fn_arg1;
653
int fn_arg2;
654
} fn;
655
} body;
656
/*
657
* Optional callback called when item is being applied,
658
* and its context.
659
*/
660
struct ng_apply_info *apply;
661
u_int depth;
662
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
663
char *lastfile;
664
int lastline;
665
TAILQ_ENTRY(ng_item) all; /* all existing items */
666
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
667
};
668
669
#define NGQF_TYPE 0x03 /* MASK of content definition */
670
#define NGQF_MESG 0x00 /* the queue element is a message */
671
#define NGQF_DATA 0x01 /* the queue element is data */
672
#define NGQF_FN 0x02 /* the queue element is a function */
673
#define NGQF_FN2 0x03 /* the queue element is a new function */
674
675
#define NGQF_RW 0x04 /* MASK for wanted queue mode */
676
#define NGQF_READER 0x04 /* wants to be a reader */
677
#define NGQF_WRITER 0x00 /* wants to be a writer */
678
679
#define NGQF_QMODE 0x08 /* MASK for how it was queued */
680
#define NGQF_QREADER 0x08 /* was queued as a reader */
681
#define NGQF_QWRITER 0x00 /* was queued as a writer */
682
683
/*
684
* Get the mbuf (etc) out of an item.
685
* Sets the value in the item to NULL in case we need to call NG_FREE_ITEM()
686
* with it, (to avoid freeing the things twice).
687
* If you don't want to zero out the item then realise that the
688
* item still owns it.
689
* Retaddr is different. There are no references on that. It's just a number.
690
* The debug versions must be either all used everywhere or not at all.
691
*/
692
693
#define _NGI_M(i) ((i)->body.da_m)
694
#define _NGI_MSG(i) ((i)->body.msg.msg_msg)
695
#define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr)
696
#define _NGI_FN(i) ((i)->body.fn.fn_fn.fn_fn)
697
#define _NGI_FN2(i) ((i)->body.fn.fn_fn.fn_fn2)
698
#define _NGI_ARG1(i) ((i)->body.fn.fn_arg1)
699
#define _NGI_ARG2(i) ((i)->body.fn.fn_arg2)
700
#define _NGI_NODE(i) ((i)->el_dest)
701
#define _NGI_HOOK(i) ((i)->el_hook)
702
#define _NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0)
703
#define _NGI_CLR_HOOK(i) do { \
704
hook_p _hook = _NGI_HOOK(i); \
705
if (_hook) { \
706
_NG_HOOK_UNREF(_hook); \
707
_NGI_HOOK(i) = NULL; \
708
} \
709
} while (0)
710
#define _NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0)
711
#define _NGI_CLR_NODE(i) do { \
712
node_p _node = _NGI_NODE(i); \
713
if (_node) { \
714
_NG_NODE_UNREF(_node); \
715
_NGI_NODE(i) = NULL; \
716
} \
717
} while (0)
718
719
#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/
720
void dumpitem(item_p item, char *file, int line);
721
static __inline void _ngi_check(item_p item, char *file, int line) ;
722
static __inline struct mbuf ** _ngi_m(item_p item, char *file, int line) ;
723
static __inline ng_ID_t * _ngi_retaddr(item_p item, char *file, int line);
724
static __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ;
725
static __inline ng_item_fn ** _ngi_fn(item_p item, char *file, int line) ;
726
static __inline ng_item_fn2 ** _ngi_fn2(item_p item, char *file, int line) ;
727
static __inline void ** _ngi_arg1(item_p item, char *file, int line) ;
728
static __inline int * _ngi_arg2(item_p item, char *file, int line) ;
729
static __inline node_p _ngi_node(item_p item, char *file, int line);
730
static __inline hook_p _ngi_hook(item_p item, char *file, int line);
731
732
static __inline void
733
_ngi_check(item_p item, char *file, int line)
734
{
735
(item)->lastline = line;
736
(item)->lastfile = file;
737
}
738
739
static __inline struct mbuf **
740
_ngi_m(item_p item, char *file, int line)
741
{
742
_ngi_check(item, file, line);
743
return (&_NGI_M(item));
744
}
745
746
static __inline struct ng_mesg **
747
_ngi_msg(item_p item, char *file, int line)
748
{
749
_ngi_check(item, file, line);
750
return (&_NGI_MSG(item));
751
}
752
753
static __inline ng_ID_t *
754
_ngi_retaddr(item_p item, char *file, int line)
755
{
756
_ngi_check(item, file, line);
757
return (&_NGI_RETADDR(item));
758
}
759
760
static __inline ng_item_fn **
761
_ngi_fn(item_p item, char *file, int line)
762
{
763
_ngi_check(item, file, line);
764
return (&_NGI_FN(item));
765
}
766
767
static __inline ng_item_fn2 **
768
_ngi_fn2(item_p item, char *file, int line)
769
{
770
_ngi_check(item, file, line);
771
return (&_NGI_FN2(item));
772
}
773
774
static __inline void **
775
_ngi_arg1(item_p item, char *file, int line)
776
{
777
_ngi_check(item, file, line);
778
return (&_NGI_ARG1(item));
779
}
780
781
static __inline int *
782
_ngi_arg2(item_p item, char *file, int line)
783
{
784
_ngi_check(item, file, line);
785
return (&_NGI_ARG2(item));
786
}
787
788
static __inline node_p
789
_ngi_node(item_p item, char *file, int line)
790
{
791
_ngi_check(item, file, line);
792
return (_NGI_NODE(item));
793
}
794
795
static __inline hook_p
796
_ngi_hook(item_p item, char *file, int line)
797
{
798
_ngi_check(item, file, line);
799
return (_NGI_HOOK(item));
800
}
801
802
#define NGI_M(i) (*_ngi_m(i, _NN_))
803
#define NGI_MSG(i) (*_ngi_msg(i, _NN_))
804
#define NGI_RETADDR(i) (*_ngi_retaddr(i, _NN_))
805
#define NGI_FN(i) (*_ngi_fn(i, _NN_))
806
#define NGI_FN2(i) (*_ngi_fn2(i, _NN_))
807
#define NGI_ARG1(i) (*_ngi_arg1(i, _NN_))
808
#define NGI_ARG2(i) (*_ngi_arg2(i, _NN_))
809
#define NGI_HOOK(i) _ngi_hook(i, _NN_)
810
#define NGI_NODE(i) _ngi_node(i, _NN_)
811
#define NGI_SET_HOOK(i,h) \
812
do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0)
813
#define NGI_CLR_HOOK(i) \
814
do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0)
815
#define NGI_SET_NODE(i,n) \
816
do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0)
817
#define NGI_CLR_NODE(i) \
818
do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0)
819
820
#define NG_FREE_ITEM(item) \
821
do { \
822
_ngi_check(item, _NN_); \
823
ng_free_item((item)); \
824
} while (0)
825
826
#define SAVE_LINE(item) \
827
do { \
828
(item)->lastline = __LINE__; \
829
(item)->lastfile = __FILE__; \
830
} while (0)
831
832
#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
833
834
#define NGI_M(i) _NGI_M(i)
835
#define NGI_MSG(i) _NGI_MSG(i)
836
#define NGI_RETADDR(i) _NGI_RETADDR(i)
837
#define NGI_FN(i) _NGI_FN(i)
838
#define NGI_FN2(i) _NGI_FN2(i)
839
#define NGI_ARG1(i) _NGI_ARG1(i)
840
#define NGI_ARG2(i) _NGI_ARG2(i)
841
#define NGI_NODE(i) _NGI_NODE(i)
842
#define NGI_HOOK(i) _NGI_HOOK(i)
843
#define NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h)
844
#define NGI_CLR_HOOK(i) _NGI_CLR_HOOK(i)
845
#define NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n)
846
#define NGI_CLR_NODE(i) _NGI_CLR_NODE(i)
847
848
#define NG_FREE_ITEM(item) ng_free_item((item))
849
#define SAVE_LINE(item) do {} while (0)
850
851
#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
852
853
#define NGI_GET_M(i,m) \
854
do { \
855
(m) = NGI_M(i); \
856
_NGI_M(i) = NULL; \
857
} while (0)
858
859
#define NGI_GET_MSG(i,m) \
860
do { \
861
(m) = NGI_MSG(i); \
862
_NGI_MSG(i) = NULL; \
863
} while (0)
864
865
#define NGI_GET_NODE(i,n) /* YOU NOW HAVE THE REFERENCE */ \
866
do { \
867
(n) = NGI_NODE(i); \
868
_NGI_NODE(i) = NULL; \
869
} while (0)
870
871
#define NGI_GET_HOOK(i,h) \
872
do { \
873
(h) = NGI_HOOK(i); \
874
_NGI_HOOK(i) = NULL; \
875
} while (0)
876
877
#define NGI_SET_WRITER(i) ((i)->el_flags &= ~NGQF_QMODE)
878
#define NGI_SET_READER(i) ((i)->el_flags |= NGQF_QREADER)
879
880
#define NGI_QUEUED_READER(i) ((i)->el_flags & NGQF_QREADER)
881
#define NGI_QUEUED_WRITER(i) (((i)->el_flags & NGQF_QMODE) == NGQF_QWRITER)
882
883
/**********************************************************************
884
* Data macros. Send, manipulate and free.
885
**********************************************************************/
886
/*
887
* Assuming the data is already ok, just set the new address and send
888
*/
889
#define NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags) \
890
do { \
891
(error) = \
892
ng_address_hook(NULL, (item), (hook), NG_NOFLAGS); \
893
if (error == 0) { \
894
SAVE_LINE(item); \
895
(error) = ng_snd_item((item), (flags)); \
896
} \
897
(item) = NULL; \
898
} while (0)
899
#define NG_FWD_ITEM_HOOK(error, item, hook) \
900
NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, NG_NOFLAGS)
901
902
/*
903
* Forward a data packet. Mbuf pointer is updated to new value. We
904
* presume you dealt with the old one when you update it to the new one
905
* (or it maybe the old one). We got a packet and possibly had to modify
906
* the mbuf. You should probably use NGI_GET_M() if you are going to use
907
* this too.
908
*/
909
#define NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, flags) \
910
do { \
911
NGI_M(item) = (m); \
912
(m) = NULL; \
913
NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags); \
914
} while (0)
915
#define NG_FWD_NEW_DATA(error, item, hook, m) \
916
NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, NG_NOFLAGS)
917
918
/* Send a previously unpackaged mbuf. XXX: This should be called
919
* NG_SEND_DATA in future, but this name is kept for compatibility
920
* reasons.
921
*/
922
#define NG_SEND_DATA_FLAGS(error, hook, m, flags) \
923
do { \
924
item_p _item; \
925
if ((_item = ng_package_data((m), flags))) { \
926
NG_FWD_ITEM_HOOK_FLAGS(error, _item, hook, flags);\
927
} else { \
928
(error) = ENOMEM; \
929
} \
930
(m) = NULL; \
931
} while (0)
932
933
#define NG_SEND_DATA_ONLY(error, hook, m) \
934
NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS)
935
/* NG_SEND_DATA() compat for meta-data times */
936
#define NG_SEND_DATA(error, hook, m, x) \
937
NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS)
938
939
#define NG_FREE_MSG(msg) \
940
do { \
941
if ((msg)) { \
942
free((msg), M_NETGRAPH_MSG); \
943
(msg) = NULL; \
944
} \
945
} while (0)
946
947
#define NG_FREE_M(m) \
948
do { \
949
if ((m)) { \
950
m_freem((m)); \
951
(m) = NULL; \
952
} \
953
} while (0)
954
955
/*****************************************
956
* Message macros
957
*****************************************/
958
959
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr) \
960
do { \
961
item_p _item; \
962
if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
963
(msg) = NULL; \
964
(error) = ENOMEM; \
965
break; \
966
} \
967
if (((error) = ng_address_hook((here), (_item), \
968
(hook), (retaddr))) == 0) { \
969
SAVE_LINE(_item); \
970
(error) = ng_snd_item((_item), 0); \
971
} \
972
(msg) = NULL; \
973
} while (0)
974
975
#define NG_SEND_MSG_PATH(error, here, msg, path, retaddr) \
976
do { \
977
item_p _item; \
978
if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
979
(msg) = NULL; \
980
(error) = ENOMEM; \
981
break; \
982
} \
983
if (((error) = ng_address_path((here), (_item), \
984
(path), (retaddr))) == 0) { \
985
SAVE_LINE(_item); \
986
(error) = ng_snd_item((_item), 0); \
987
} \
988
(msg) = NULL; \
989
} while (0)
990
991
#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr) \
992
do { \
993
item_p _item; \
994
if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\
995
(msg) = NULL; \
996
(error) = ENOMEM; \
997
break; \
998
} \
999
if (((error) = ng_address_ID((here), (_item), \
1000
(ID), (retaddr))) == 0) { \
1001
SAVE_LINE(_item); \
1002
(error) = ng_snd_item((_item), 0); \
1003
} \
1004
(msg) = NULL; \
1005
} while (0)
1006
1007
/*
1008
* Redirect the message to the next hop using the given hook.
1009
* ng_retarget_msg() frees the item if there is an error
1010
* and returns an error code. It returns 0 on success.
1011
*/
1012
#define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr) \
1013
do { \
1014
if (((error) = ng_address_hook((here), (item), \
1015
(hook), (retaddr))) == 0) { \
1016
SAVE_LINE(item); \
1017
(error) = ng_snd_item((item), 0); \
1018
} \
1019
(item) = NULL; \
1020
} while (0)
1021
1022
/*
1023
* Send a queue item back to it's originator with a response message.
1024
* Assume original message was removed and freed separatly.
1025
*/
1026
#define NG_RESPOND_MSG(error, here, item, resp) \
1027
do { \
1028
if (resp) { \
1029
ng_ID_t _dest = NGI_RETADDR(item); \
1030
NGI_RETADDR(item) = 0; \
1031
NGI_MSG(item) = resp; \
1032
if ((error = ng_address_ID((here), (item), \
1033
_dest, 0)) == 0) { \
1034
SAVE_LINE(item); \
1035
(error) = ng_snd_item((item), NG_QUEUE);\
1036
} \
1037
} else \
1038
NG_FREE_ITEM(item); \
1039
(item) = NULL; \
1040
} while (0)
1041
1042
/***********************************************************************
1043
******** Structures Definitions and Macros for defining a node *******
1044
***********************************************************************
1045
*
1046
* Here we define the structures needed to actually define a new node
1047
* type.
1048
*/
1049
1050
/*
1051
* Command list -- each node type specifies the command that it knows
1052
* how to convert between ASCII and binary using an array of these.
1053
* The last element in the array must be a terminator with cookie=0.
1054
*/
1055
1056
struct ng_cmdlist {
1057
u_int32_t cookie; /* command typecookie */
1058
int cmd; /* command number */
1059
const char *name; /* command name */
1060
const struct ng_parse_type *mesgType; /* args if !NGF_RESP */
1061
const struct ng_parse_type *respType; /* args if NGF_RESP */
1062
};
1063
1064
/*
1065
* Structure of a node type
1066
* If data is sent to the "rcvdata()" entrypoint then the system
1067
* may decide to defer it until later by queing it with the normal netgraph
1068
* input queuing system. This is decidde by the HK_QUEUE flag being set in
1069
* the flags word of the peer (receiving) hook. The dequeuing mechanism will
1070
* ensure it is not requeued again.
1071
* Note the input queueing system is to allow modules
1072
* to 'release the stack' or to pass data across spl layers.
1073
* The data will be redelivered as soon as the NETISR code runs
1074
* which may be almost immediately. A node may also do it's own queueing
1075
* for other reasons (e.g. device output queuing).
1076
*/
1077
struct ng_type {
1078
u_int32_t version; /* must equal NG_API_VERSION */
1079
const char *name; /* Unique type name */
1080
modeventhand_t mod_event; /* Module event handler (optional) */
1081
ng_constructor_t *constructor; /* Node constructor */
1082
ng_rcvmsg_t *rcvmsg; /* control messages come here */
1083
ng_close_t *close; /* warn about forthcoming shutdown */
1084
ng_shutdown_t *shutdown; /* reset, and free resources */
1085
ng_newhook_t *newhook; /* first notification of new hook */
1086
ng_findhook_t *findhook; /* only if you have lots of hooks */
1087
ng_connect_t *connect; /* final notification of new hook */
1088
ng_rcvdata_t *rcvdata; /* data comes here */
1089
ng_disconnect_t *disconnect; /* notify on disconnect */
1090
1091
const struct ng_cmdlist *cmdlist; /* commands we can convert */
1092
1093
/* R/W data private to the base netgraph code DON'T TOUCH! */
1094
LIST_ENTRY(ng_type) types; /* linked list of all types */
1095
int refs; /* number of instances */
1096
};
1097
1098
/*
1099
* Use the NETGRAPH_INIT() macro to link a node type into the
1100
* netgraph system. This works for types compiled into the kernel
1101
* as well as KLD modules. The first argument should be the type
1102
* name (eg, echo) and the second a pointer to the type struct.
1103
*
1104
* If a different link time is desired, e.g., a device driver that
1105
* needs to install its netgraph type before probing, use the
1106
* NETGRAPH_INIT_ORDERED() macro instead. Device drivers probably
1107
* want to use SI_SUB_DRIVERS/SI_ORDER_FIRST.
1108
*/
1109
1110
#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \
1111
static moduledata_t ng_##typename##_mod = { \
1112
"ng_" #typename, \
1113
ng_mod_event, \
1114
(typestructp) \
1115
}; \
1116
DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \
1117
MODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \
1118
NG_ABI_VERSION, \
1119
NG_ABI_VERSION)
1120
1121
#define NETGRAPH_INIT(tn, tp) \
1122
NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_MIDDLE)
1123
1124
/* Special malloc() type for netgraph structs and ctrl messages */
1125
/* Only these two types should be visible to nodes */
1126
MALLOC_DECLARE(M_NETGRAPH);
1127
MALLOC_DECLARE(M_NETGRAPH_MSG);
1128
1129
/* declare the base of the netgraph sysclt hierarchy */
1130
/* but only if this file cares about sysctls */
1131
#ifdef SYSCTL_DECL
1132
SYSCTL_DECL(_net_graph);
1133
#endif
1134
1135
/*
1136
* Methods that the nodes can use.
1137
* Many of these methods should usually NOT be used directly but via
1138
* Macros above.
1139
*/
1140
int ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr);
1141
int ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
1142
int ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr);
1143
int ng_bypass(hook_p hook1, hook_p hook2);
1144
hook_p ng_findhook(node_p node, const char *name);
1145
struct ng_type *ng_findtype(const char *type);
1146
int ng_make_node_common(struct ng_type *typep, node_p *nodep);
1147
int ng_name_node(node_p node, const char *name);
1148
node_p ng_name2noderef(node_p node, const char *name);
1149
int ng_newtype(struct ng_type *tp);
1150
ng_ID_t ng_node2ID(node_cp node);
1151
item_p ng_package_data(struct mbuf *m, int flags);
1152
item_p ng_package_msg(struct ng_mesg *msg, int flags);
1153
item_p ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg);
1154
void ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr);
1155
int ng_rmhook_self(hook_p hook); /* if a node wants to kill a hook */
1156
int ng_rmnode_self(node_p here); /* if a node wants to suicide */
1157
int ng_rmtype(struct ng_type *tp);
1158
int ng_snd_item(item_p item, int queue);
1159
int ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void *arg1,
1160
int arg2);
1161
int ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void *arg1,
1162
int arg2, int flags);
1163
int ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn,
1164
void *arg1, int arg2, int flags);
1165
int ng_uncallout(struct callout *c, node_p node);
1166
int ng_uncallout_drain(struct callout *c, node_p node);
1167
int ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
1168
ng_item_fn *fn, void * arg1, int arg2);
1169
#define ng_callout_init(c) callout_init(c, 1)
1170
1171
/* Flags for netgraph functions. */
1172
#define NG_NOFLAGS 0x00000000 /* no special options */
1173
#define NG_QUEUE 0x00000001 /* enqueue item, don't dispatch */
1174
#define NG_WAITOK 0x00000002 /* use M_WAITOK, etc. */
1175
/* XXXGL: NG_PROGRESS unused since ng_base.c rev. 1.136. Should be deleted? */
1176
#define NG_PROGRESS 0x00000004 /* return EINPROGRESS if queued */
1177
#define NG_REUSE_ITEM 0x00000008 /* supplied item should be reused */
1178
1179
/*
1180
* prototypes the user should DEFINITELY not use directly
1181
*/
1182
void ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */
1183
int ng_mod_event(module_t mod, int what, void *arg);
1184
1185
/*
1186
* Tag definitions and constants
1187
*/
1188
1189
#define NG_TAG_PRIO 1
1190
1191
struct ng_tag_prio {
1192
struct m_tag tag;
1193
char priority;
1194
char discardability;
1195
};
1196
1197
#define NG_PRIO_CUTOFF 32
1198
#define NG_PRIO_LINKSTATE 64
1199
1200
/* Macros and declarations to keep compatibility with metadata, which
1201
* is obsoleted now. To be deleted.
1202
*/
1203
typedef void *meta_p;
1204
#define _NGI_META(i) NULL
1205
#define NGI_META(i) NULL
1206
#define NG_FREE_META(meta)
1207
#define NGI_GET_META(i,m)
1208
#define ng_copy_meta(meta) NULL
1209
1210
/*
1211
* Mark the current thread when called from the outbound path of the
1212
* network stack, in order to enforce queuing on ng nodes calling into
1213
* the inbound network stack path.
1214
*/
1215
#define NG_OUTBOUND_THREAD_REF() \
1216
curthread->td_ng_outbound++
1217
#define NG_OUTBOUND_THREAD_UNREF() \
1218
do { \
1219
curthread->td_ng_outbound--; \
1220
KASSERT(curthread->td_ng_outbound >= 0, \
1221
("%s: negative td_ng_outbound", __func__)); \
1222
} while (0)
1223
1224
#endif /* _NETGRAPH_NETGRAPH_H_ */
1225
1226