1 /* 2 * netgraph.h 3 * 4 * Copyright (c) 1996-1999 Whistle Communications, Inc. 5 * All rights reserved. 6 * 7 * Subject to the following obligations and disclaimer of warranty, use and 8 * redistribution of this software, in source or object code forms, with or 9 * without modifications are expressly permitted by Whistle Communications; 10 * provided, however, that: 11 * 1. Any and all reproductions of the source or object code must include the 12 * copyright notice above and the following disclaimer of warranties; and 13 * 2. No rights are granted, in any manner or form, to use Whistle 14 * Communications, Inc. trademarks, including the mark "WHISTLE 15 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 16 * such appears in the above copyright notice or in the software. 17 * 18 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 19 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 20 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 21 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 23 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 24 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 25 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 26 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 27 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 28 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 29 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 34 * OF SUCH DAMAGE. 35 * 36 * Author: Julian Elischer <julian@freebsd.org> 37 * 38 * $FreeBSD$ 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_ 1 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 /* debugging options */ 55 #define NETGRAPH_DEBUG 56 #define NG_SEPARATE_MALLOC /* make modules use their own malloc types */ 57 58 /* 59 * This defines the in-kernel binary interface version. 60 * It is possible to change this but leave the external message 61 * API the same. Each type also has it's own cookies for versioning as well. 62 * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug 63 * modules. 64 */ 65 #define _NG_ABI_VERSION 6 66 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 67 #define NG_ABI_VERSION (_NG_ABI_VERSION + 0x10000) 68 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 69 #define NG_ABI_VERSION _NG_ABI_VERSION 70 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 71 72 73 /* 74 * Forward references for the basic structures so we can 75 * define the typedefs and use them in the structures themselves. 76 */ 77 struct ng_hook ; 78 struct ng_node ; 79 struct ng_item ; 80 typedef struct ng_item *item_p; 81 typedef struct ng_node *node_p; 82 typedef struct ng_hook *hook_p; 83 84 /* node method definitions */ 85 typedef int ng_constructor_t(node_p node); 86 typedef int ng_shutdown_t(node_p node); 87 typedef int ng_newhook_t(node_p node, hook_p hook, const char *name); 88 typedef hook_p ng_findhook_t(node_p node, const char *name); 89 typedef int ng_connect_t(hook_p hook); 90 typedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook); 91 typedef int ng_rcvdata_t(hook_p hook, item_p item); 92 typedef int ng_disconnect_t(hook_p hook); 93 typedef int ng_rcvitem (node_p node, hook_p hook, item_p item); 94 95 /*********************************************************************** 96 ***************** Hook Structure and Methods ************************** 97 *********************************************************************** 98 * 99 * Structure of a hook 100 */ 101 struct ng_hook { 102 char hk_name[NG_HOOKLEN+1]; /* what this node knows this link as */ 103 void *hk_private; /* node dependant ID for this hook */ 104 int hk_flags; /* info about this hook/link */ 105 int hk_refs; /* dont actually free this till 0 */ 106 struct ng_hook *hk_peer; /* the other end of this link */ 107 struct ng_node *hk_node; /* The node this hook is attached to */ 108 LIST_ENTRY(ng_hook) hk_hooks; /* linked list of all hooks on node */ 109 ng_rcvmsg_t *hk_rcvmsg; /* control messages come here */ 110 ng_rcvdata_t *hk_rcvdata; /* data comes here */ 111 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 112 #define HK_MAGIC 0x78573011 113 int hk_magic; 114 char *lastfile; 115 int lastline; 116 SLIST_ENTRY(ng_hook) hk_all; /* all existing items */ 117 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 118 }; 119 /* Flags for a hook */ 120 #define HK_INVALID 0x0001 /* don't trust it! */ 121 #define HK_QUEUE 0x0002 /* queue for later delivery */ 122 #define HK_FORCE_WRITER 0x0004 /* Incoming data queued as a writer */ 123 #define HK_DEAD 0x0008 /* This is the dead hook.. don't free */ 124 125 /* 126 * Public Methods for hook 127 * If you can't do it with these you probably shouldn;t be doing it. 128 */ 129 void ng_unref_hook(hook_p hook); /* don't move this */ 130 #define _NG_HOOK_REF(hook) atomic_add_int(&(hook)->hk_refs, 1) 131 #define _NG_HOOK_NAME(hook) ((hook)->hk_name) 132 #define _NG_HOOK_UNREF(hook) ng_unref_hook(hook) 133 #define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0) 134 #define _NG_HOOK_SET_RCVMSG(hook, val) do {(hook)->hk_rcvmsg = val;} while (0) 135 #define _NG_HOOK_SET_RCVDATA(hook, val) do {(hook)->hk_rcvdata = val;} while (0) 136 #define _NG_HOOK_PRIVATE(hook) ((hook)->hk_private) 137 #define _NG_HOOK_NOT_VALID(hook) ((hook)->hk_flags & HK_INVALID) 138 #define _NG_HOOK_IS_VALID(hook) (!((hook)->hk_flags & HK_INVALID)) 139 #define _NG_HOOK_NODE(hook) ((hook)->hk_node) /* only rvalue! */ 140 #define _NG_HOOK_PEER(hook) ((hook)->hk_peer) /* only rvalue! */ 141 #define _NG_HOOK_FORCE_WRITER(hook) \ 142 do { hook->hk_flags |= HK_FORCE_WRITER; } while (0) 143 #define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0) 144 145 /* Some shortcuts */ 146 #define NG_PEER_NODE(hook) NG_HOOK_NODE(NG_HOOK_PEER(hook)) 147 #define NG_PEER_HOOK_NAME(hook) NG_HOOK_NAME(NG_HOOK_PEER(hook)) 148 #define NG_PEER_NODE_NAME(hook) NG_NODE_NAME(NG_PEER_NODE(hook)) 149 150 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 151 #define _NN_ __FILE__,__LINE__ 152 void dumphook (hook_p hook, char *file, int line); 153 static __inline void _chkhook(hook_p hook, char *file, int line); 154 static __inline void _ng_hook_ref(hook_p hook, char * file, int line); 155 static __inline char * _ng_hook_name(hook_p hook, char * file, int line); 156 static __inline void _ng_hook_unref(hook_p hook, char * file, int line); 157 static __inline void _ng_hook_set_private(hook_p hook, 158 void * val, char * file, int line); 159 static __inline void _ng_hook_set_rcvmsg(hook_p hook, 160 ng_rcvmsg_t *val, char * file, int line); 161 static __inline void _ng_hook_set_rcvdata(hook_p hook, 162 ng_rcvdata_t *val, char * file, int line); 163 static __inline void * _ng_hook_private(hook_p hook, char * file, int line); 164 static __inline int _ng_hook_not_valid(hook_p hook, char * file, int line); 165 static __inline int _ng_hook_is_valid(hook_p hook, char * file, int line); 166 static __inline node_p _ng_hook_node(hook_p hook, char * file, int line); 167 static __inline hook_p _ng_hook_peer(hook_p hook, char * file, int line); 168 static __inline void _ng_hook_force_writer(hook_p hook, char * file, 169 int line); 170 static __inline void _ng_hook_force_queue(hook_p hook, char * file, int line); 171 172 static void __inline 173 _chkhook(hook_p hook, char *file, int line) 174 { 175 if (hook->hk_magic != HK_MAGIC) { 176 printf("Accessing freed hook "); 177 dumphook(hook, file, line); 178 } 179 hook->lastline = line; 180 hook->lastfile = file; 181 } 182 183 static __inline void 184 _ng_hook_ref(hook_p hook, char * file, int line) 185 { 186 _chkhook(hook, file, line); 187 _NG_HOOK_REF(hook); 188 } 189 190 static __inline char * 191 _ng_hook_name(hook_p hook, char * file, int line) 192 { 193 _chkhook(hook, file, line); 194 return (_NG_HOOK_NAME(hook)); 195 } 196 197 static __inline void 198 _ng_hook_unref(hook_p hook, char * file, int line) 199 { 200 _chkhook(hook, file, line); 201 _NG_HOOK_UNREF(hook); 202 } 203 204 static __inline void 205 _ng_hook_set_private(hook_p hook, void *val, char * file, int line) 206 { 207 _chkhook(hook, file, line); 208 _NG_HOOK_SET_PRIVATE(hook, val); 209 } 210 211 static __inline void 212 _ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line) 213 { 214 _chkhook(hook, file, line); 215 _NG_HOOK_SET_RCVMSG(hook, val); 216 } 217 218 static __inline void 219 _ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line) 220 { 221 _chkhook(hook, file, line); 222 _NG_HOOK_SET_RCVDATA(hook, val); 223 } 224 225 static __inline void * 226 _ng_hook_private(hook_p hook, char * file, int line) 227 { 228 _chkhook(hook, file, line); 229 return (_NG_HOOK_PRIVATE(hook)); 230 } 231 232 static __inline int 233 _ng_hook_not_valid(hook_p hook, char * file, int line) 234 { 235 _chkhook(hook, file, line); 236 return (_NG_HOOK_NOT_VALID(hook)); 237 } 238 239 static __inline int 240 _ng_hook_is_valid(hook_p hook, char * file, int line) 241 { 242 _chkhook(hook, file, line); 243 return (_NG_HOOK_IS_VALID(hook)); 244 } 245 246 static __inline node_p 247 _ng_hook_node(hook_p hook, char * file, int line) 248 { 249 _chkhook(hook, file, line); 250 return (_NG_HOOK_NODE(hook)); 251 } 252 253 static __inline hook_p 254 _ng_hook_peer(hook_p hook, char * file, int line) 255 { 256 _chkhook(hook, file, line); 257 return (_NG_HOOK_PEER(hook)); 258 } 259 260 static __inline void 261 _ng_hook_force_writer(hook_p hook, char * file, int line) 262 { 263 _chkhook(hook, file, line); 264 _NG_HOOK_FORCE_WRITER(hook); 265 } 266 267 static __inline void 268 _ng_hook_force_queue(hook_p hook, char * file, int line) 269 { 270 _chkhook(hook, file, line); 271 _NG_HOOK_FORCE_QUEUE(hook); 272 } 273 274 275 #define NG_HOOK_REF(hook) _ng_hook_ref(hook, _NN_) 276 #define NG_HOOK_NAME(hook) _ng_hook_name(hook, _NN_) 277 #define NG_HOOK_UNREF(hook) _ng_hook_unref(hook, _NN_) 278 #define NG_HOOK_SET_PRIVATE(hook, val) _ng_hook_set_private(hook, val, _NN_) 279 #define NG_HOOK_SET_RCVMSG(hook, val) _ng_hook_set_rcvmsg(hook, val, _NN_) 280 #define NG_HOOK_SET_RCVDATA(hook, val) _ng_hook_set_rcvdata(hook, val, _NN_) 281 #define NG_HOOK_PRIVATE(hook) _ng_hook_private(hook, _NN_) 282 #define NG_HOOK_NOT_VALID(hook) _ng_hook_not_valid(hook, _NN_) 283 #define NG_HOOK_IS_VALID(hook) _ng_hook_is_valid(hook, _NN_) 284 #define NG_HOOK_NODE(hook) _ng_hook_node(hook, _NN_) 285 #define NG_HOOK_PEER(hook) _ng_hook_peer(hook, _NN_) 286 #define NG_HOOK_FORCE_WRITER(hook) _ng_hook_force_writer(hook, _NN_) 287 #define NG_HOOK_FORCE_QUEUE(hook) _ng_hook_force_queue(hook, _NN_) 288 289 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 290 291 #define NG_HOOK_REF(hook) _NG_HOOK_REF(hook) 292 #define NG_HOOK_NAME(hook) _NG_HOOK_NAME(hook) 293 #define NG_HOOK_UNREF(hook) _NG_HOOK_UNREF(hook) 294 #define NG_HOOK_SET_PRIVATE(hook, val) _NG_HOOK_SET_PRIVATE(hook, val) 295 #define NG_HOOK_SET_RCVMSG(hook, val) _NG_HOOK_SET_RCVMSG(hook, val) 296 #define NG_HOOK_SET_RCVDATA(hook, val) _NG_HOOK_SET_RCVDATA(hook, val) 297 #define NG_HOOK_PRIVATE(hook) _NG_HOOK_PRIVATE(hook) 298 #define NG_HOOK_NOT_VALID(hook) _NG_HOOK_NOT_VALID(hook) 299 #define NG_HOOK_IS_VALID(hook) _NG_HOOK_IS_VALID(hook) 300 #define NG_HOOK_NODE(hook) _NG_HOOK_NODE(hook) 301 #define NG_HOOK_PEER(hook) _NG_HOOK_PEER(hook) 302 #define NG_HOOK_FORCE_WRITER(hook) _NG_HOOK_FORCE_WRITER(hook) 303 #define NG_HOOK_FORCE_QUEUE(hook) _NG_HOOK_FORCE_QUEUE(hook) 304 305 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 306 307 /*********************************************************************** 308 ***************** Node Structure and Methods ************************** 309 *********************************************************************** 310 * Structure of a node 311 * including the eembedded queue structure. 312 * 313 * The structure for queueing Netgraph request items 314 * embedded in the node structure 315 */ 316 struct ng_queue { 317 u_long q_flags; 318 struct mtx q_mtx; 319 item_p queue; 320 item_p *last; 321 struct ng_node *q_node; /* find the front of the node.. */ 322 }; 323 324 struct ng_node { 325 char nd_name[NG_NODELEN+1]; /* optional globally unique name */ 326 struct ng_type *nd_type; /* the installed 'type' */ 327 int nd_flags; /* see below for bit definitions */ 328 int nd_refs; /* # of references to this node */ 329 int nd_numhooks; /* number of hooks */ 330 void *nd_private; /* node type dependant node ID */ 331 ng_ID_t nd_ID; /* Unique per node */ 332 LIST_HEAD(hooks, ng_hook) nd_hooks; /* linked list of node hooks */ 333 LIST_ENTRY(ng_node) nd_nodes; /* linked list of all nodes */ 334 LIST_ENTRY(ng_node) nd_idnodes; /* ID hash collision list */ 335 TAILQ_ENTRY(ng_node) nd_work; /* nodes with work to do */ 336 struct ng_queue nd_input_queue; /* input queue for locking */ 337 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 338 #define ND_MAGIC 0x59264837 339 int nd_magic; 340 char *lastfile; 341 int lastline; 342 SLIST_ENTRY(ng_node) nd_all; /* all existing nodes */ 343 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 344 }; 345 346 /* Flags for a node */ 347 #define NG_INVALID 0x00000001 /* free when refs go to 0 */ 348 #define NG_WORKQ 0x00000002 /* node is on the work queue */ 349 #define NG_FORCE_WRITER 0x00000004 /* Never multithread this node */ 350 #define NG_CLOSING 0x00000008 /* ng_rmnode() at work */ 351 #define NG_REALLY_DIE 0x00000010 /* "persistant" node is unloading */ 352 #define NGF_TYPE1 0x10000000 /* reserved for type specific storage */ 353 #define NGF_TYPE2 0x20000000 /* reserved for type specific storage */ 354 #define NGF_TYPE3 0x40000000 /* reserved for type specific storage */ 355 #define NGF_TYPE4 0x80000000 /* reserved for type specific storage */ 356 357 /* 358 * Public methods for nodes. 359 * If you can't do it with these you probably shouldn't be doing it. 360 */ 361 int ng_unref_node(node_p node); /* don't move this */ 362 #define _NG_NODE_NAME(node) ((node)->nd_name + 0) 363 #define _NG_NODE_HAS_NAME(node) ((node)->nd_name[0] + 0) 364 #define _NG_NODE_ID(node) ((node)->nd_ID + 0) 365 #define _NG_NODE_REF(node) atomic_add_int(&(node)->nd_refs, 1) 366 #define _NG_NODE_UNREF(node) ng_unref_node(node) 367 #define _NG_NODE_SET_PRIVATE(node, val) do {(node)->nd_private = val;} while (0) 368 #define _NG_NODE_PRIVATE(node) ((node)->nd_private) 369 #define _NG_NODE_IS_VALID(node) (!((node)->nd_flags & NG_INVALID)) 370 #define _NG_NODE_NOT_VALID(node) ((node)->nd_flags & NG_INVALID) 371 #define _NG_NODE_NUMHOOKS(node) ((node)->nd_numhooks + 0) /* rvalue */ 372 #define _NG_NODE_FORCE_WRITER(node) \ 373 do{ node->nd_flags |= NG_FORCE_WRITER; }while (0) 374 #define _NG_NODE_REALLY_DIE(node) \ 375 do{ node->nd_flags |= (NG_REALLY_DIE|NG_INVALID); }while (0) 376 /* 377 * The hook iterator. 378 * This macro will call a function of type ng_fn_eachhook for each 379 * hook attached to the node. If the function returns 0, then the 380 * iterator will stop and return a pointer to the hook that returned 0. 381 */ 382 typedef int ng_fn_eachhook(hook_p hook, void* arg); 383 #define _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 384 do { \ 385 hook_p _hook; \ 386 (rethook) = NULL; \ 387 LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) { \ 388 if ((fn)(_hook, arg) == 0) { \ 389 (rethook) = _hook; \ 390 break; \ 391 } \ 392 } \ 393 } while (0) 394 395 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 396 void dumpnode(node_p node, char *file, int line); 397 static void __inline _chknode(node_p node, char *file, int line); 398 static __inline char * _ng_node_name(node_p node, char *file, int line); 399 static __inline int _ng_node_has_name(node_p node, char *file, int line); 400 static __inline ng_ID_t _ng_node_id(node_p node, char *file, int line); 401 void ng_ref_node(node_p node); 402 static __inline void _ng_node_ref(node_p node, char *file, int line); 403 static __inline int _ng_node_unref(node_p node, char *file, int line); 404 static __inline void _ng_node_set_private(node_p node, void * val, 405 char *file, int line); 406 static __inline void * _ng_node_private(node_p node, char *file, int line); 407 static __inline int _ng_node_is_valid(node_p node, char *file, int line); 408 static __inline int _ng_node_not_valid(node_p node, char *file, int line); 409 static __inline int _ng_node_numhooks(node_p node, char *file, int line); 410 static __inline void _ng_node_force_writer(node_p node, char *file, int line); 411 static __inline hook_p _ng_node_foreach_hook(node_p node, 412 ng_fn_eachhook *fn, void *arg, char *file, int line); 413 414 static void __inline 415 _chknode(node_p node, char *file, int line) 416 { 417 if (node->nd_magic != ND_MAGIC) { 418 printf("Accessing freed node "); 419 dumpnode(node, file, line); 420 } 421 node->lastline = line; 422 node->lastfile = file; 423 } 424 425 static __inline char * 426 _ng_node_name(node_p node, char *file, int line) 427 { 428 _chknode(node, file, line); 429 return(_NG_NODE_NAME(node)); 430 } 431 432 static __inline int 433 _ng_node_has_name(node_p node, char *file, int line) 434 { 435 _chknode(node, file, line); 436 return(_NG_NODE_HAS_NAME(node)); 437 } 438 439 static __inline ng_ID_t 440 _ng_node_id(node_p node, char *file, int line) 441 { 442 _chknode(node, file, line); 443 return(_NG_NODE_ID(node)); 444 } 445 446 static __inline void 447 _ng_node_ref(node_p node, char *file, int line) 448 { 449 _chknode(node, file, line); 450 /*_NG_NODE_REF(node);*/ 451 ng_ref_node(node); 452 } 453 454 static __inline int 455 _ng_node_unref(node_p node, char *file, int line) 456 { 457 _chknode(node, file, line); 458 return (_NG_NODE_UNREF(node)); 459 } 460 461 static __inline void 462 _ng_node_set_private(node_p node, void * val, char *file, int line) 463 { 464 _chknode(node, file, line); 465 _NG_NODE_SET_PRIVATE(node, val); 466 } 467 468 static __inline void * 469 _ng_node_private(node_p node, char *file, int line) 470 { 471 _chknode(node, file, line); 472 return (_NG_NODE_PRIVATE(node)); 473 } 474 475 static __inline int 476 _ng_node_is_valid(node_p node, char *file, int line) 477 { 478 _chknode(node, file, line); 479 return(_NG_NODE_IS_VALID(node)); 480 } 481 482 static __inline int 483 _ng_node_not_valid(node_p node, char *file, int line) 484 { 485 _chknode(node, file, line); 486 return(_NG_NODE_NOT_VALID(node)); 487 } 488 489 static __inline int 490 _ng_node_numhooks(node_p node, char *file, int line) 491 { 492 _chknode(node, file, line); 493 return(_NG_NODE_NUMHOOKS(node)); 494 } 495 496 static __inline void 497 _ng_node_force_writer(node_p node, char *file, int line) 498 { 499 _chknode(node, file, line); 500 _NG_NODE_FORCE_WRITER(node); 501 } 502 503 static __inline void 504 _ng_node_really_die(node_p node, char *file, int line) 505 { 506 _chknode(node, file, line); 507 _NG_NODE_REALLY_DIE(node); 508 } 509 510 static __inline hook_p 511 _ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg, 512 char *file, int line) 513 { 514 hook_p hook; 515 _chknode(node, file, line); 516 _NG_NODE_FOREACH_HOOK(node, fn, arg, hook); 517 return (hook); 518 } 519 520 #define NG_NODE_NAME(node) _ng_node_name(node, _NN_) 521 #define NG_NODE_HAS_NAME(node) _ng_node_has_name(node, _NN_) 522 #define NG_NODE_ID(node) _ng_node_id(node, _NN_) 523 #define NG_NODE_REF(node) _ng_node_ref(node, _NN_) 524 #define NG_NODE_UNREF(node) _ng_node_unref(node, _NN_) 525 #define NG_NODE_SET_PRIVATE(node, val) _ng_node_set_private(node, val, _NN_) 526 #define NG_NODE_PRIVATE(node) _ng_node_private(node, _NN_) 527 #define NG_NODE_IS_VALID(node) _ng_node_is_valid(node, _NN_) 528 #define NG_NODE_NOT_VALID(node) _ng_node_not_valid(node, _NN_) 529 #define NG_NODE_FORCE_WRITER(node) _ng_node_force_writer(node, _NN_) 530 #define NG_NODE_REALLY_DIE(node) _ng_node_really_die(node, _NN_) 531 #define NG_NODE_NUMHOOKS(node) _ng_node_numhooks(node, _NN_) 532 #define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 533 do { \ 534 rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \ 535 } while (0) 536 537 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 538 539 #define NG_NODE_NAME(node) _NG_NODE_NAME(node) 540 #define NG_NODE_HAS_NAME(node) _NG_NODE_HAS_NAME(node) 541 #define NG_NODE_ID(node) _NG_NODE_ID(node) 542 #define NG_NODE_REF(node) _NG_NODE_REF(node) 543 #define NG_NODE_UNREF(node) _NG_NODE_UNREF(node) 544 #define NG_NODE_SET_PRIVATE(node, val) _NG_NODE_SET_PRIVATE(node, val) 545 #define NG_NODE_PRIVATE(node) _NG_NODE_PRIVATE(node) 546 #define NG_NODE_IS_VALID(node) _NG_NODE_IS_VALID(node) 547 #define NG_NODE_NOT_VALID(node) _NG_NODE_NOT_VALID(node) 548 #define NG_NODE_FORCE_WRITER(node) _NG_NODE_FORCE_WRITER(node) 549 #define NG_NODE_REALLY_DIE(node) _NG_NODE_REALLY_DIE(node) 550 #define NG_NODE_NUMHOOKS(node) _NG_NODE_NUMHOOKS(node) 551 #define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 552 _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) 553 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 554 555 /*********************************************************************** 556 ***************** Meta Data Structures and Methods ******************** 557 *********************************************************************** 558 * 559 * The structure that holds meta_data about a data packet (e.g. priority) 560 * Nodes might add or subtract options as needed if there is room. 561 * They might reallocate the struct to make more room if they need to. 562 * Meta-data is still experimental. 563 */ 564 struct meta_field_header { 565 u_long cookie; /* cookie for the field. Skip fields you don't 566 * know about (same cookie as in messgaes) */ 567 u_short type; /* field ID */ 568 u_short len; /* total len of this field including extra 569 * data */ 570 char data[0]; /* data starts here */ 571 }; 572 573 /* To zero out an option 'in place' set it's cookie to this */ 574 #define NGM_INVALID_COOKIE 865455152 575 576 /* This part of the metadata is always present if the pointer is non NULL */ 577 struct ng_meta { 578 char priority; /* -ve is less priority, 0 is default */ 579 char discardability; /* higher is less valuable.. discard first */ 580 u_short allocated_len; /* amount malloc'd */ 581 u_short used_len; /* sum of all fields, options etc. */ 582 u_short flags; /* see below.. generic flags */ 583 struct meta_field_header options[0]; /* add as (if) needed */ 584 }; 585 typedef struct ng_meta *meta_p; 586 587 /* Flags for meta-data */ 588 #define NGMF_TEST 0x01 /* discard at the last moment before sending */ 589 #define NGMF_TRACE 0x02 /* trace when handing this data to a node */ 590 591 /*********************************************************************** 592 ************* Node Queue and Item Structures and Methods ************** 593 *********************************************************************** 594 * 595 */ 596 typedef void ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2); 597 struct ng_item { 598 u_long el_flags; 599 item_p el_next; 600 node_p el_dest; /* The node it will be applied against (or NULL) */ 601 hook_p el_hook; /* Entering hook. Optional in Control messages */ 602 union { 603 struct { 604 struct mbuf *da_m; 605 meta_p da_meta; 606 } data; 607 struct { 608 struct ng_mesg *msg_msg; 609 ng_ID_t msg_retaddr; 610 } msg; 611 struct { 612 ng_item_fn *fn_fn; 613 void *fn_arg1; 614 int fn_arg2; 615 } fn; 616 } body; 617 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 618 char *lastfile; 619 int lastline; 620 TAILQ_ENTRY(ng_item) all; /* all existing items */ 621 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 622 }; 623 624 #define NGQF_TYPE 0x03 /* MASK of content definition */ 625 #define NGQF_MESG 0x00 /* the queue element is a message */ 626 #define NGQF_DATA 0x01 /* the queue element is data */ 627 #define NGQF_FN 0x02 /* the queue element is a function */ 628 #define NGQF_UNDEF 0x03 /* UNDEFINED */ 629 630 #define NGQF_RW 0x04 /* MASK for queue entry read/write */ 631 #define NGQF_READER 0x04 /* queued as a reader */ 632 #define NGQF_WRITER 0x00 /* queued as a writer */ 633 634 #define NGQF_FREE 0x08 635 636 /* 637 * Get the mbuf (etc) out of an item. 638 * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM() 639 * with it, (to avoid freeing the things twice). 640 * If you don't want to zero out the item then realise that the 641 * item still owns it. 642 * Retaddr is different. There are no references on that. It's just a number. 643 * The debug versions must be either all used everywhere or not at all. 644 */ 645 646 #define _NGI_M(i) ((i)->body.data.da_m) 647 #define _NGI_META(i) ((i)->body.data.da_meta) 648 #define _NGI_MSG(i) ((i)->body.msg.msg_msg) 649 #define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr) 650 #define _NGI_FN(i) ((i)->body.fn.fn_fn) 651 #define _NGI_ARG1(i) ((i)->body.fn.fn_arg1) 652 #define _NGI_ARG2(i) ((i)->body.fn.fn_arg2) 653 #define _NGI_NODE(i) ((i)->el_dest) 654 #define _NGI_HOOK(i) ((i)->el_hook) 655 #define _NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0) 656 #define _NGI_CLR_HOOK(i) do { \ 657 hook_p _hook = _NGI_HOOK(i); \ 658 if (_hook) { \ 659 _NG_HOOK_UNREF(_hook); \ 660 _NGI_HOOK(i) = NULL; \ 661 } \ 662 } while (0) 663 #define _NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0) 664 #define _NGI_CLR_NODE(i) do { \ 665 node_p _node = _NGI_NODE(i); \ 666 if (_node) { \ 667 _NG_NODE_UNREF(_node); \ 668 _NGI_NODE(i) = NULL; \ 669 } \ 670 } while (0) 671 672 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 673 void dumpitem(item_p item, char *file, int line); 674 static __inline void _ngi_check(item_p item, char *file, int line) ; 675 static __inline struct mbuf ** _ngi_m(item_p item, char *file, int line) ; 676 static __inline meta_p * _ngi_meta(item_p item, char *file, int line) ; 677 static __inline ng_ID_t * _ngi_retaddr(item_p item, char *file, int line); 678 static __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ; 679 static __inline ng_item_fn ** _ngi_fn(item_p item, char *file, int line) ; 680 static __inline void ** _ngi_arg1(item_p item, char *file, int line) ; 681 static __inline int * _ngi_arg2(item_p item, char *file, int line) ; 682 static __inline node_p _ngi_node(item_p item, char *file, int line); 683 static __inline hook_p _ngi_hook(item_p item, char *file, int line); 684 685 static __inline void 686 _ngi_check(item_p item, char *file, int line) 687 { 688 if (item->el_flags & NGQF_FREE) { 689 dumpitem(item, file, line); 690 panic ("free item!"); 691 } 692 (item)->lastline = line; 693 (item)->lastfile = file; 694 } 695 696 static __inline struct mbuf ** 697 _ngi_m(item_p item, char *file, int line) 698 { 699 _ngi_check(item, file, line); 700 return (&_NGI_M(item)); 701 } 702 703 static __inline meta_p * 704 _ngi_meta(item_p item, char *file, int line) 705 { 706 _ngi_check(item, file, line); 707 return (&_NGI_META(item)); 708 } 709 710 static __inline struct ng_mesg ** 711 _ngi_msg(item_p item, char *file, int line) 712 { 713 _ngi_check(item, file, line); 714 return (&_NGI_MSG(item)); 715 } 716 717 static __inline ng_ID_t * 718 _ngi_retaddr(item_p item, char *file, int line) 719 { 720 _ngi_check(item, file, line); 721 return (&_NGI_RETADDR(item)); 722 } 723 724 static __inline ng_item_fn ** 725 _ngi_fn(item_p item, char *file, int line) 726 { 727 _ngi_check(item, file, line); 728 return (&_NGI_FN(item)); 729 } 730 731 static __inline void ** 732 _ngi_arg1(item_p item, char *file, int line) 733 { 734 _ngi_check(item, file, line); 735 return (&_NGI_ARG1(item)); 736 } 737 738 static __inline int * 739 _ngi_arg2(item_p item, char *file, int line) 740 { 741 _ngi_check(item, file, line); 742 return (&_NGI_ARG2(item)); 743 } 744 745 static __inline node_p 746 _ngi_node(item_p item, char *file, int line) 747 { 748 _ngi_check(item, file, line); 749 return (_NGI_NODE(item)); 750 } 751 752 static __inline hook_p 753 _ngi_hook(item_p item, char *file, int line) 754 { 755 _ngi_check(item, file, line); 756 return (_NGI_HOOK(item)); 757 } 758 759 #define NGI_M(i) (*_ngi_m(i, _NN_)) 760 #define NGI_META(i) (*_ngi_meta(i, _NN_)) 761 #define NGI_MSG(i) (*_ngi_msg(i, _NN_)) 762 #define NGI_RETADDR(i) (*_ngi_retaddr(i, _NN_)) 763 #define NGI_FN(i) (*_ngi_fn(i, _NN_)) 764 #define NGI_ARG1(i) (*_ngi_arg1(i, _NN_)) 765 #define NGI_ARG2(i) (*_ngi_arg2(i, _NN_)) 766 #define NGI_HOOK(i) _ngi_hook(i, _NN_) 767 #define NGI_NODE(i) _ngi_node(i, _NN_) 768 #define NGI_SET_HOOK(i,h) \ 769 do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0) 770 #define NGI_CLR_HOOK(i) \ 771 do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0) 772 #define NGI_SET_NODE(i,n) \ 773 do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0) 774 #define NGI_CLR_NODE(i) \ 775 do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0) 776 777 #define NG_FREE_ITEM(item) \ 778 do { \ 779 _ngi_check(item, _NN_); \ 780 ng_free_item((item)); \ 781 } while (0) 782 783 #define SAVE_LINE(item) \ 784 do { \ 785 (item)->lastline = __LINE__; \ 786 (item)->lastfile = __FILE__; \ 787 } while (0) 788 789 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 790 791 #define NGI_M(i) _NGI_M(i) 792 #define NGI_META(i) _NGI_META(i) 793 #define NGI_MSG(i) _NGI_MSG(i) 794 #define NGI_RETADDR(i) _NGI_RETADDR(i) 795 #define NGI_FN(i) _NGI_FN(i) 796 #define NGI_ARG1(i) _NGI_ARG1(i) 797 #define NGI_ARG2(i) _NGI_ARG2(i) 798 #define NGI_NODE(i) _NGI_NODE(i) 799 #define NGI_HOOK(i) _NGI_HOOK(i) 800 #define NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h) 801 #define NGI_CLR_HOOK(i) _NGI_CLR_HOOK(i) 802 #define NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n) 803 #define NGI_CLR_NODE(i) _NGI_CLR_NODE(i) 804 805 #define NG_FREE_ITEM(item) ng_free_item((item)) 806 #define SAVE_LINE(item) do {} while (0) 807 808 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 809 810 #define NGI_GET_M(i,m) \ 811 do { \ 812 (m) = NGI_M(i); \ 813 _NGI_M(i) = NULL; \ 814 } while (0) 815 816 #define NGI_GET_META(i,m) \ 817 do { \ 818 (m) = NGI_META(i); \ 819 _NGI_META(i) = NULL; \ 820 } while (0) 821 822 #define NGI_GET_MSG(i,m) \ 823 do { \ 824 (m) = NGI_MSG(i); \ 825 _NGI_MSG(i) = NULL; \ 826 } while (0) 827 828 #define NGI_GET_NODE(i,n) /* YOU NOW HAVE THE REFERENCE */ \ 829 do { \ 830 (n) = NGI_NODE(i); \ 831 _NGI_NODE(i) = NULL; \ 832 } while (0) 833 834 #define NGI_GET_HOOK(i,h) \ 835 do { \ 836 (h) = NGI_HOOK(i); \ 837 _NGI_HOOK(i) = NULL; \ 838 } while (0) 839 840 841 /********************************************************************** 842 * Data macros. Send, manipulate and free. 843 **********************************************************************/ 844 /* 845 * Assuming the data is already ok, just set the new address and send 846 */ 847 #define NG_FWD_ITEM_HOOK(error, item, hook) \ 848 do { \ 849 (error) = \ 850 ng_address_hook(NULL, (item), (hook), 0); \ 851 if (error == 0) { \ 852 SAVE_LINE(item); \ 853 (error) = ng_snd_item((item), 0); \ 854 } \ 855 (item) = NULL; \ 856 } while (0) 857 858 /* 859 * Forward a data packet with no new meta-data. 860 * old metadata is passed along without change. 861 * Mbuf pointer is updated to new value. We presume you dealt with the 862 * old one when you update it to the new one (or it maybe the old one). 863 * We got a packet and possibly had to modify the mbuf. 864 * You should probably use NGI_GET_M() if you are going to use this too 865 */ 866 #define NG_FWD_NEW_DATA(error, item, hook, m) \ 867 do { \ 868 NGI_M(item) = (m); \ 869 (m) = NULL; \ 870 NG_FWD_ITEM_HOOK(error, item, hook); \ 871 } while (0) 872 873 /* Send a previously unpackaged mbuf when we have no metadata to send */ 874 #define NG_SEND_DATA_ONLY(error, hook, m) \ 875 do { \ 876 item_p _item; \ 877 if ((_item = ng_package_data((m), NULL))) { \ 878 NG_FWD_ITEM_HOOK(error, _item, hook); \ 879 } else { \ 880 (error) = ENOMEM; \ 881 } \ 882 (m) = NULL; \ 883 } while (0) 884 885 /* Send previously unpackeged data and metadata. */ 886 #define NG_SEND_DATA(error, hook, m, meta) \ 887 do { \ 888 item_p _item; \ 889 if ((_item = ng_package_data((m), (meta)))) { \ 890 NG_FWD_ITEM_HOOK(error, _item, hook); \ 891 } else { \ 892 (error) = ENOMEM; \ 893 } \ 894 (m) = NULL; \ 895 (meta) = NULL; \ 896 } while (0) 897 898 #define NG_FREE_MSG(msg) \ 899 do { \ 900 if ((msg)) { \ 901 FREE((msg), M_NETGRAPH_MSG); \ 902 (msg) = NULL; \ 903 } \ 904 } while (0) 905 906 #define NG_FREE_META(meta) \ 907 do { \ 908 if ((meta)) { \ 909 FREE((meta), M_NETGRAPH_META); \ 910 (meta) = NULL; \ 911 } \ 912 } while (0) 913 914 #define NG_FREE_M(m) \ 915 do { \ 916 if ((m)) { \ 917 m_freem((m)); \ 918 (m) = NULL; \ 919 } \ 920 } while (0) 921 922 /***************************************** 923 * Message macros 924 *****************************************/ 925 926 #define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr) \ 927 do { \ 928 item_p _item; \ 929 if ((_item = ng_package_msg(msg)) == NULL) { \ 930 (msg) = NULL; \ 931 (error) = ENOMEM; \ 932 break; \ 933 } \ 934 if (((error) = ng_address_hook((here), (_item), \ 935 (hook), (retaddr))) == 0) { \ 936 SAVE_LINE(_item); \ 937 (error) = ng_snd_item((_item), 0); \ 938 } \ 939 (msg) = NULL; \ 940 } while (0) 941 942 #define NG_SEND_MSG_PATH(error, here, msg, path, retaddr) \ 943 do { \ 944 item_p _item; \ 945 if ((_item = ng_package_msg(msg)) == NULL) { \ 946 (msg) = NULL; \ 947 (error) = ENOMEM; \ 948 break; \ 949 } \ 950 if (((error) = ng_address_path((here), (_item), \ 951 (path), (retaddr))) == 0) { \ 952 SAVE_LINE(_item); \ 953 (error) = ng_snd_item((_item), 0); \ 954 } \ 955 (msg) = NULL; \ 956 } while (0) 957 958 #define NG_SEND_MSG_ID(error, here, msg, ID, retaddr) \ 959 do { \ 960 item_p _item; \ 961 if ((_item = ng_package_msg(msg)) == NULL) { \ 962 (msg) = NULL; \ 963 (error) = ENOMEM; \ 964 break; \ 965 } \ 966 if (((error) = ng_address_ID((here), (_item), \ 967 (ID), (retaddr))) == 0) { \ 968 SAVE_LINE(_item); \ 969 (error) = ng_snd_item((_item), 0); \ 970 } \ 971 (msg) = NULL; \ 972 } while (0) 973 974 /* 975 * Redirect the message to the next hop using the given hook. 976 * ng_retarget_msg() frees the item if there is an error 977 * and returns an error code. It returns 0 on success. 978 */ 979 #define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr) \ 980 do { \ 981 if (((error) = ng_address_hook((here), (item), \ 982 (hook), (retaddr))) == 0) { \ 983 SAVE_LINE(item); \ 984 (error) = ng_snd_item((item), 0); \ 985 } \ 986 (item) = NULL; \ 987 } while (0) 988 989 /* 990 * Send a queue item back to it's originator with a response message. 991 * Assume original message was removed and freed separatly. 992 */ 993 #define NG_RESPOND_MSG(error, here, item, resp) \ 994 do { \ 995 if (resp) { \ 996 ng_ID_t _dest = NGI_RETADDR(item); \ 997 NGI_RETADDR(item) = 0; \ 998 NGI_MSG(item) = resp; \ 999 if ((ng_address_ID((here), (item), \ 1000 _dest, 0)) == 0) { \ 1001 SAVE_LINE(item); \ 1002 (error) = ng_snd_item((item), 1); \ 1003 } else { \ 1004 (error) = EINVAL; \ 1005 } \ 1006 } else { \ 1007 NG_FREE_ITEM(item); \ 1008 } \ 1009 (item) = NULL; \ 1010 } while (0) 1011 1012 1013 /*********************************************************************** 1014 ******** Structures Definitions and Macros for defining a node ******* 1015 *********************************************************************** 1016 * 1017 * Here we define the structures needed to actually define a new node 1018 * type. 1019 */ 1020 1021 /* 1022 * Command list -- each node type specifies the command that it knows 1023 * how to convert between ASCII and binary using an array of these. 1024 * The last element in the array must be a terminator with cookie=0. 1025 */ 1026 1027 struct ng_cmdlist { 1028 u_int32_t cookie; /* command typecookie */ 1029 int cmd; /* command number */ 1030 const char *name; /* command name */ 1031 const struct ng_parse_type *mesgType; /* args if !NGF_RESP */ 1032 const struct ng_parse_type *respType; /* args if NGF_RESP */ 1033 }; 1034 1035 /* 1036 * Structure of a node type 1037 * If data is sent to the "rcvdata()" entrypoint then the system 1038 * may decide to defer it until later by queing it with the normal netgraph 1039 * input queuing system. This is decidde by the HK_QUEUE flag being set in 1040 * the flags word of the peer (receiving) hook. The dequeuing mechanism will 1041 * ensure it is not requeued again. 1042 * Note the input queueing system is to allow modules 1043 * to 'release the stack' or to pass data across spl layers. 1044 * The data will be redelivered as soon as the NETISR code runs 1045 * which may be almost immediatly. A node may also do it's own queueing 1046 * for other reasons (e.g. device output queuing). 1047 */ 1048 struct ng_type { 1049 1050 u_int32_t version; /* must equal NG_API_VERSION */ 1051 const char *name; /* Unique type name */ 1052 modeventhand_t mod_event; /* Module event handler (optional) */ 1053 ng_constructor_t *constructor; /* Node constructor */ 1054 ng_rcvmsg_t *rcvmsg; /* control messages come here */ 1055 ng_shutdown_t *shutdown; /* reset, and free resources */ 1056 ng_newhook_t *newhook; /* first notification of new hook */ 1057 ng_findhook_t *findhook; /* only if you have lots of hooks */ 1058 ng_connect_t *connect; /* final notification of new hook */ 1059 ng_rcvdata_t *rcvdata; /* data comes here */ 1060 ng_disconnect_t *disconnect; /* notify on disconnect */ 1061 1062 const struct ng_cmdlist *cmdlist; /* commands we can convert */ 1063 1064 /* R/W data private to the base netgraph code DON'T TOUCH! */ 1065 LIST_ENTRY(ng_type) types; /* linked list of all types */ 1066 int refs; /* number of instances */ 1067 }; 1068 1069 /* 1070 * Use the NETGRAPH_INIT() macro to link a node type into the 1071 * netgraph system. This works for types compiled into the kernel 1072 * as well as KLD modules. The first argument should be the type 1073 * name (eg, echo) and the second a pointer to the type struct. 1074 * 1075 * If a different link time is desired, e.g., a device driver that 1076 * needs to install its netgraph type before probing, use the 1077 * NETGRAPH_INIT_ORDERED() macro instead. Deivce drivers probably 1078 * want to use SI_SUB_DRIVERS instead of SI_SUB_PSEUDO. 1079 */ 1080 1081 #define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \ 1082 static moduledata_t ng_##typename##_mod = { \ 1083 "ng_" #typename, \ 1084 ng_mod_event, \ 1085 (typestructp) \ 1086 }; \ 1087 DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \ 1088 MODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \ 1089 NG_ABI_VERSION, \ 1090 NG_ABI_VERSION) 1091 1092 #define NETGRAPH_INIT(tn, tp) \ 1093 NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY) 1094 1095 /* Special malloc() type for netgraph structs and ctrl messages */ 1096 /* Only these two types should be visible to nodes */ 1097 MALLOC_DECLARE(M_NETGRAPH); 1098 MALLOC_DECLARE(M_NETGRAPH_MSG); 1099 MALLOC_DECLARE(M_NETGRAPH_META); 1100 1101 /* declare the base of the netgraph sysclt hierarchy */ 1102 /* but only if this file cares about sysctls */ 1103 #ifdef SYSCTL_DECL 1104 SYSCTL_DECL(_net_graph); 1105 #endif 1106 1107 /* 1108 * Methods that the nodes can use. 1109 * Many of these methods should usually NOT be used directly but via 1110 * Macros above. 1111 */ 1112 int ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr); 1113 int ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr); 1114 int ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr); 1115 meta_p ng_copy_meta(meta_p meta); 1116 hook_p ng_findhook(node_p node, const char *name); 1117 int ng_make_node_common(struct ng_type *typep, node_p *nodep); 1118 int ng_name_node(node_p node, const char *name); 1119 int ng_newtype(struct ng_type *tp); 1120 ng_ID_t ng_node2ID(node_p node); 1121 item_p ng_package_data(struct mbuf *m, meta_p meta); 1122 item_p ng_package_msg(struct ng_mesg *msg); 1123 item_p ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg); 1124 void ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr); 1125 int ng_rmhook_self(hook_p hook); /* if a node wants to kill a hook */ 1126 int ng_rmnode_self(node_p here); /* if a node wants to suicide */ 1127 int ng_rmtype(struct ng_type *tp); 1128 int ng_snd_item(item_p item, int queue); 1129 int ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, 1130 void *arg1, int arg2); 1131 int ng_untimeout(struct callout_handle handle, node_p node); 1132 struct callout_handle 1133 ng_timeout(node_p node, hook_p hook, int ticks, 1134 ng_item_fn *fn, void * arg1, int arg2); 1135 1136 /* 1137 * prototypes the user should DEFINITLY not use directly 1138 */ 1139 void ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */ 1140 int ng_mod_event(module_t mod, int what, void *arg); 1141 1142 #endif /* _NETGRAPH_NETGRAPH_H_ */ 1143 1144