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 LIST_FOREACH(hook, &((node)->nd_hooks), hk_hooks) { \ 387 if ((fn)(hook, arg) == 0) { \ 388 (rethook) = hook; \ 389 break; \ 390 } \ 391 } \ 392 } while (0) 393 394 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 395 void dumpnode(node_p node, char *file, int line); 396 static void __inline _chknode(node_p node, char *file, int line); 397 static __inline char * _ng_node_name(node_p node, char *file, int line); 398 static __inline int _ng_node_has_name(node_p node, char *file, int line); 399 static __inline ng_ID_t _ng_node_id(node_p node, char *file, int line); 400 void ng_ref_node(node_p node); 401 static __inline void _ng_node_ref(node_p node, char *file, int line); 402 static __inline int _ng_node_unref(node_p node, char *file, int line); 403 static __inline void _ng_node_set_private(node_p node, void * val, 404 char *file, int line); 405 static __inline void * _ng_node_private(node_p node, char *file, int line); 406 static __inline int _ng_node_is_valid(node_p node, char *file, int line); 407 static __inline int _ng_node_not_valid(node_p node, char *file, int line); 408 static __inline int _ng_node_numhooks(node_p node, char *file, int line); 409 static __inline void _ng_node_force_writer(node_p node, char *file, int line); 410 static __inline hook_p _ng_node_foreach_hook(node_p node, 411 ng_fn_eachhook *fn, void *arg, char *file, int line); 412 413 static void __inline 414 _chknode(node_p node, char *file, int line) 415 { 416 if (node->nd_magic != ND_MAGIC) { 417 printf("Accessing freed node "); 418 dumpnode(node, file, line); 419 } 420 node->lastline = line; 421 node->lastfile = file; 422 } 423 424 static __inline char * 425 _ng_node_name(node_p node, char *file, int line) 426 { 427 _chknode(node, file, line); 428 return(_NG_NODE_NAME(node)); 429 } 430 431 static __inline int 432 _ng_node_has_name(node_p node, char *file, int line) 433 { 434 _chknode(node, file, line); 435 return(_NG_NODE_HAS_NAME(node)); 436 } 437 438 static __inline ng_ID_t 439 _ng_node_id(node_p node, char *file, int line) 440 { 441 _chknode(node, file, line); 442 return(_NG_NODE_ID(node)); 443 } 444 445 static __inline void 446 _ng_node_ref(node_p node, char *file, int line) 447 { 448 _chknode(node, file, line); 449 /*_NG_NODE_REF(node);*/ 450 ng_ref_node(node); 451 } 452 453 static __inline int 454 _ng_node_unref(node_p node, char *file, int line) 455 { 456 _chknode(node, file, line); 457 return (_NG_NODE_UNREF(node)); 458 } 459 460 static __inline void 461 _ng_node_set_private(node_p node, void * val, char *file, int line) 462 { 463 _chknode(node, file, line); 464 _NG_NODE_SET_PRIVATE(node, val); 465 } 466 467 static __inline void * 468 _ng_node_private(node_p node, char *file, int line) 469 { 470 _chknode(node, file, line); 471 return (_NG_NODE_PRIVATE(node)); 472 } 473 474 static __inline int 475 _ng_node_is_valid(node_p node, char *file, int line) 476 { 477 _chknode(node, file, line); 478 return(_NG_NODE_IS_VALID(node)); 479 } 480 481 static __inline int 482 _ng_node_not_valid(node_p node, char *file, int line) 483 { 484 _chknode(node, file, line); 485 return(_NG_NODE_NOT_VALID(node)); 486 } 487 488 static __inline int 489 _ng_node_numhooks(node_p node, char *file, int line) 490 { 491 _chknode(node, file, line); 492 return(_NG_NODE_NUMHOOKS(node)); 493 } 494 495 static __inline void 496 _ng_node_force_writer(node_p node, char *file, int line) 497 { 498 _chknode(node, file, line); 499 _NG_NODE_FORCE_WRITER(node); 500 } 501 502 static __inline void 503 _ng_node_really_die(node_p node, char *file, int line) 504 { 505 _chknode(node, file, line); 506 _NG_NODE_REALLY_DIE(node); 507 } 508 509 static __inline hook_p 510 _ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg, 511 char *file, int line) 512 { 513 hook_p hook; 514 _chknode(node, file, line); 515 _NG_NODE_FOREACH_HOOK(node, fn, arg, hook); 516 return (hook); 517 } 518 519 #define NG_NODE_NAME(node) _ng_node_name(node, _NN_) 520 #define NG_NODE_HAS_NAME(node) _ng_node_has_name(node, _NN_) 521 #define NG_NODE_ID(node) _ng_node_id(node, _NN_) 522 #define NG_NODE_REF(node) _ng_node_ref(node, _NN_) 523 #define NG_NODE_UNREF(node) _ng_node_unref(node, _NN_) 524 #define NG_NODE_SET_PRIVATE(node, val) _ng_node_set_private(node, val, _NN_) 525 #define NG_NODE_PRIVATE(node) _ng_node_private(node, _NN_) 526 #define NG_NODE_IS_VALID(node) _ng_node_is_valid(node, _NN_) 527 #define NG_NODE_NOT_VALID(node) _ng_node_not_valid(node, _NN_) 528 #define NG_NODE_FORCE_WRITER(node) _ng_node_force_writer(node, _NN_) 529 #define NG_NODE_REALLY_DIE(node) _ng_node_really_die(node, _NN_) 530 #define NG_NODE_NUMHOOKS(node) _ng_node_numhooks(node, _NN_) 531 #define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 532 do { \ 533 rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \ 534 } while (0) 535 536 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 537 538 #define NG_NODE_NAME(node) _NG_NODE_NAME(node) 539 #define NG_NODE_HAS_NAME(node) _NG_NODE_HAS_NAME(node) 540 #define NG_NODE_ID(node) _NG_NODE_ID(node) 541 #define NG_NODE_REF(node) _NG_NODE_REF(node) 542 #define NG_NODE_UNREF(node) _NG_NODE_UNREF(node) 543 #define NG_NODE_SET_PRIVATE(node, val) _NG_NODE_SET_PRIVATE(node, val) 544 #define NG_NODE_PRIVATE(node) _NG_NODE_PRIVATE(node) 545 #define NG_NODE_IS_VALID(node) _NG_NODE_IS_VALID(node) 546 #define NG_NODE_NOT_VALID(node) _NG_NODE_NOT_VALID(node) 547 #define NG_NODE_FORCE_WRITER(node) _NG_NODE_FORCE_WRITER(node) 548 #define NG_NODE_REALLY_DIE(node) _NG_NODE_REALLY_DIE(node) 549 #define NG_NODE_NUMHOOKS(node) _NG_NODE_NUMHOOKS(node) 550 #define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 551 _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) 552 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 553 554 /*********************************************************************** 555 ***************** Meta Data Structures and Methods ******************** 556 *********************************************************************** 557 * 558 * The structure that holds meta_data about a data packet (e.g. priority) 559 * Nodes might add or subtract options as needed if there is room. 560 * They might reallocate the struct to make more room if they need to. 561 * Meta-data is still experimental. 562 */ 563 struct meta_field_header { 564 u_long cookie; /* cookie for the field. Skip fields you don't 565 * know about (same cookie as in messgaes) */ 566 u_short type; /* field ID */ 567 u_short len; /* total len of this field including extra 568 * data */ 569 char data[0]; /* data starts here */ 570 }; 571 572 /* To zero out an option 'in place' set it's cookie to this */ 573 #define NGM_INVALID_COOKIE 865455152 574 575 /* This part of the metadata is always present if the pointer is non NULL */ 576 struct ng_meta { 577 char priority; /* -ve is less priority, 0 is default */ 578 char discardability; /* higher is less valuable.. discard first */ 579 u_short allocated_len; /* amount malloc'd */ 580 u_short used_len; /* sum of all fields, options etc. */ 581 u_short flags; /* see below.. generic flags */ 582 struct meta_field_header options[0]; /* add as (if) needed */ 583 }; 584 typedef struct ng_meta *meta_p; 585 586 /* Flags for meta-data */ 587 #define NGMF_TEST 0x01 /* discard at the last moment before sending */ 588 #define NGMF_TRACE 0x02 /* trace when handing this data to a node */ 589 590 /*********************************************************************** 591 ************* Node Queue and Item Structures and Methods ************** 592 *********************************************************************** 593 * 594 */ 595 typedef void ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2); 596 struct ng_item { 597 u_long el_flags; 598 item_p el_next; 599 node_p el_dest; /* The node it will be applied against (or NULL) */ 600 hook_p el_hook; /* Entering hook. Optional in Control messages */ 601 union { 602 struct { 603 struct mbuf *da_m; 604 meta_p da_meta; 605 } data; 606 struct { 607 struct ng_mesg *msg_msg; 608 ng_ID_t msg_retaddr; 609 } msg; 610 struct { 611 ng_item_fn *fn_fn; 612 void *fn_arg1; 613 int fn_arg2; 614 } fn; 615 } body; 616 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 617 char *lastfile; 618 int lastline; 619 TAILQ_ENTRY(ng_item) all; /* all existing items */ 620 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 621 }; 622 623 #define NGQF_TYPE 0x03 /* MASK of content definition */ 624 #define NGQF_MESG 0x00 /* the queue element is a message */ 625 #define NGQF_DATA 0x01 /* the queue element is data */ 626 #define NGQF_FN 0x02 /* the queue element is a function */ 627 #define NGQF_UNDEF 0x03 /* UNDEFINED */ 628 629 #define NGQF_RW 0x04 /* MASK for queue entry read/write */ 630 #define NGQF_READER 0x04 /* queued as a reader */ 631 #define NGQF_WRITER 0x00 /* queued as a writer */ 632 633 #define NGQF_FREE 0x08 634 635 /* 636 * Get the mbuf (etc) out of an item. 637 * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM() 638 * with it, (to avoid freeing the things twice). 639 * If you don't want to zero out the item then realise that the 640 * item still owns it. 641 * Retaddr is different. There are no references on that. It's just a number. 642 * The debug versions must be either all used everywhere or not at all. 643 */ 644 645 #define _NGI_M(i) ((i)->body.data.da_m) 646 #define _NGI_META(i) ((i)->body.data.da_meta) 647 #define _NGI_MSG(i) ((i)->body.msg.msg_msg) 648 #define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr) 649 #define _NGI_FN(i) ((i)->body.fn.fn_fn) 650 #define _NGI_ARG1(i) ((i)->body.fn.fn_arg1) 651 #define _NGI_ARG2(i) ((i)->body.fn.fn_arg2) 652 #define _NGI_NODE(i) ((i)->el_dest) 653 #define _NGI_HOOK(i) ((i)->el_hook) 654 #define _NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0) 655 #define _NGI_CLR_HOOK(i) do { \ 656 hook_p hook = _NGI_HOOK(i); \ 657 if (hook) { \ 658 _NG_HOOK_UNREF(hook); \ 659 _NGI_HOOK(i) = NULL; \ 660 } \ 661 } while (0) 662 #define _NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0) 663 #define _NGI_CLR_NODE(i) do { \ 664 node_p node = _NGI_NODE(i); \ 665 if (node) { \ 666 _NG_NODE_UNREF(node); \ 667 _NGI_NODE(i) = NULL; \ 668 } \ 669 } while (0) 670 671 #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 672 void dumpitem(item_p item, char *file, int line); 673 static __inline void _ngi_check(item_p item, char *file, int line) ; 674 static __inline struct mbuf ** _ngi_m(item_p item, char *file, int line) ; 675 static __inline meta_p * _ngi_meta(item_p item, char *file, int line) ; 676 static __inline ng_ID_t * _ngi_retaddr(item_p item, char *file, int line); 677 static __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ; 678 static __inline ng_item_fn ** _ngi_fn(item_p item, char *file, int line) ; 679 static __inline void ** _ngi_arg1(item_p item, char *file, int line) ; 680 static __inline int * _ngi_arg2(item_p item, char *file, int line) ; 681 static __inline node_p _ngi_node(item_p item, char *file, int line); 682 static __inline hook_p _ngi_hook(item_p item, char *file, int line); 683 684 static __inline void 685 _ngi_check(item_p item, char *file, int line) 686 { 687 if (item->el_flags & NGQF_FREE) { 688 dumpitem(item, file, line); 689 panic ("free item!"); 690 } 691 (item)->lastline = line; 692 (item)->lastfile = file; 693 } 694 695 static __inline struct mbuf ** 696 _ngi_m(item_p item, char *file, int line) 697 { 698 _ngi_check(item, file, line); 699 return (&_NGI_M(item)); 700 } 701 702 static __inline meta_p * 703 _ngi_meta(item_p item, char *file, int line) 704 { 705 _ngi_check(item, file, line); 706 return (&_NGI_META(item)); 707 } 708 709 static __inline struct ng_mesg ** 710 _ngi_msg(item_p item, char *file, int line) 711 { 712 _ngi_check(item, file, line); 713 return (&_NGI_MSG(item)); 714 } 715 716 static __inline ng_ID_t * 717 _ngi_retaddr(item_p item, char *file, int line) 718 { 719 _ngi_check(item, file, line); 720 return (&_NGI_RETADDR(item)); 721 } 722 723 static __inline ng_item_fn ** 724 _ngi_fn(item_p item, char *file, int line) 725 { 726 _ngi_check(item, file, line); 727 return (&_NGI_FN(item)); 728 } 729 730 static __inline void ** 731 _ngi_arg1(item_p item, char *file, int line) 732 { 733 _ngi_check(item, file, line); 734 return (&_NGI_ARG1(item)); 735 } 736 737 static __inline int * 738 _ngi_arg2(item_p item, char *file, int line) 739 { 740 _ngi_check(item, file, line); 741 return (&_NGI_ARG2(item)); 742 } 743 744 static __inline node_p 745 _ngi_node(item_p item, char *file, int line) 746 { 747 _ngi_check(item, file, line); 748 return (_NGI_NODE(item)); 749 } 750 751 static __inline hook_p 752 _ngi_hook(item_p item, char *file, int line) 753 { 754 _ngi_check(item, file, line); 755 return (_NGI_HOOK(item)); 756 } 757 758 #define NGI_M(i) (*_ngi_m(i, _NN_)) 759 #define NGI_META(i) (*_ngi_meta(i, _NN_)) 760 #define NGI_MSG(i) (*_ngi_msg(i, _NN_)) 761 #define NGI_RETADDR(i) (*_ngi_retaddr(i, _NN_)) 762 #define NGI_FN(i) (*_ngi_fn(i, _NN_)) 763 #define NGI_ARG1(i) (*_ngi_arg1(i, _NN_)) 764 #define NGI_ARG2(i) (*_ngi_arg2(i, _NN_)) 765 #define NGI_HOOK(i) _ngi_hook(i, _NN_) 766 #define NGI_NODE(i) _ngi_node(i, _NN_) 767 #define NGI_SET_HOOK(i,h) \ 768 do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0) 769 #define NGI_CLR_HOOK(i) \ 770 do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0) 771 #define NGI_SET_NODE(i,n) \ 772 do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0) 773 #define NGI_CLR_NODE(i) \ 774 do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0) 775 776 #define NG_FREE_ITEM(item) \ 777 do { \ 778 _ngi_check(item, _NN_); \ 779 ng_free_item((item)); \ 780 } while (0) 781 782 #define SAVE_LINE(item) \ 783 do { \ 784 (item)->lastline = __LINE__; \ 785 (item)->lastfile = __FILE__; \ 786 } while (0) 787 788 #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 789 790 #define NGI_M(i) _NGI_M(i) 791 #define NGI_META(i) _NGI_META(i) 792 #define NGI_MSG(i) _NGI_MSG(i) 793 #define NGI_RETADDR(i) _NGI_RETADDR(i) 794 #define NGI_FN(i) _NGI_FN(i) 795 #define NGI_ARG1(i) _NGI_ARG1(i) 796 #define NGI_ARG2(i) _NGI_ARG2(i) 797 #define NGI_NODE(i) _NGI_NODE(i) 798 #define NGI_HOOK(i) _NGI_HOOK(i) 799 #define NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h) 800 #define NGI_CLR_HOOK(i) _NGI_CLR_HOOK(i) 801 #define NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n) 802 #define NGI_CLR_NODE(i) _NGI_CLR_NODE(i) 803 804 #define NG_FREE_ITEM(item) ng_free_item((item)) 805 #define SAVE_LINE(item) do {} while (0) 806 807 #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 808 809 #define NGI_GET_M(i,m) \ 810 do { \ 811 (m) = NGI_M(i); \ 812 _NGI_M(i) = NULL; \ 813 } while (0) 814 815 #define NGI_GET_META(i,m) \ 816 do { \ 817 (m) = NGI_META(i); \ 818 _NGI_META(i) = NULL; \ 819 } while (0) 820 821 #define NGI_GET_MSG(i,m) \ 822 do { \ 823 (m) = NGI_MSG(i); \ 824 _NGI_MSG(i) = NULL; \ 825 } while (0) 826 827 #define NGI_GET_NODE(i,n) /* YOU NOW HAVE THE REFERENCE */ \ 828 do { \ 829 (n) = NGI_NODE(i); \ 830 _NGI_NODE(i) = NULL; \ 831 } while (0) 832 833 #define NGI_GET_HOOK(i,h) \ 834 do { \ 835 (h) = NGI_HOOK(i); \ 836 _NGI_HOOK(i) = NULL; \ 837 } while (0) 838 839 840 /********************************************************************** 841 * Data macros. Send, manipulate and free. 842 **********************************************************************/ 843 /* 844 * Assuming the data is already ok, just set the new address and send 845 */ 846 #define NG_FWD_ITEM_HOOK(error, item, hook) \ 847 do { \ 848 (error) = \ 849 ng_address_hook(NULL, (item), (hook), NULL); \ 850 if (error == 0) { \ 851 SAVE_LINE(item); \ 852 (error) = ng_snd_item((item), 0); \ 853 } \ 854 (item) = NULL; \ 855 } while (0) 856 857 /* 858 * Forward a data packet with no new meta-data. 859 * old metadata is passed along without change. 860 * Mbuf pointer is updated to new value. We presume you dealt with the 861 * old one when you update it to the new one (or it maybe the old one). 862 * We got a packet and possibly had to modify the mbuf. 863 * You should probably use NGI_GET_M() if you are going to use this too 864 */ 865 #define NG_FWD_NEW_DATA(error, item, hook, m) \ 866 do { \ 867 NGI_M(item) = (m); \ 868 (m) = NULL; \ 869 NG_FWD_ITEM_HOOK(error, item, hook); \ 870 } while (0) 871 872 /* Send a previously unpackaged mbuf when we have no metadata to send */ 873 #define NG_SEND_DATA_ONLY(error, hook, m) \ 874 do { \ 875 item_p item; \ 876 if ((item = ng_package_data((m), NULL))) { \ 877 NG_FWD_ITEM_HOOK(error, item, hook); \ 878 } else { \ 879 (error) = ENOMEM; \ 880 } \ 881 (m) = NULL; \ 882 } while (0) 883 884 /* Send previously unpackeged data and metadata. */ 885 #define NG_SEND_DATA(error, hook, m, meta) \ 886 do { \ 887 item_p item; \ 888 if ((item = ng_package_data((m), (meta)))) { \ 889 NG_FWD_ITEM_HOOK(error, item, hook); \ 890 } else { \ 891 (error) = ENOMEM; \ 892 } \ 893 (m) = NULL; \ 894 (meta) = NULL; \ 895 } while (0) 896 897 #define NG_FREE_MSG(msg) \ 898 do { \ 899 if ((msg)) { \ 900 FREE((msg), M_NETGRAPH_MSG); \ 901 (msg) = NULL; \ 902 } \ 903 } while (0) 904 905 #define NG_FREE_META(meta) \ 906 do { \ 907 if ((meta)) { \ 908 FREE((meta), M_NETGRAPH_META); \ 909 (meta) = NULL; \ 910 } \ 911 } while (0) 912 913 #define NG_FREE_M(m) \ 914 do { \ 915 if ((m)) { \ 916 m_freem((m)); \ 917 (m) = NULL; \ 918 } \ 919 } while (0) 920 921 /***************************************** 922 * Message macros 923 *****************************************/ 924 925 #define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr) \ 926 do { \ 927 item_p item; \ 928 if ((item = ng_package_msg(msg)) == NULL) { \ 929 (msg) = NULL; \ 930 (error) = ENOMEM; \ 931 break; \ 932 } \ 933 if (((error) = ng_address_hook((here), (item), \ 934 (hook), (retaddr))) == 0) { \ 935 SAVE_LINE(item); \ 936 (error) = ng_snd_item((item), 0); \ 937 } \ 938 (msg) = NULL; \ 939 } while (0) 940 941 #define NG_SEND_MSG_PATH(error, here, msg, path, retaddr) \ 942 do { \ 943 item_p item; \ 944 if ((item = ng_package_msg(msg)) == NULL) { \ 945 (msg) = NULL; \ 946 (error) = ENOMEM; \ 947 break; \ 948 } \ 949 if (((error) = ng_address_path((here), (item), \ 950 (path), (retaddr))) == 0) { \ 951 SAVE_LINE(item); \ 952 (error) = ng_snd_item((item), 0); \ 953 } \ 954 (msg) = NULL; \ 955 } while (0) 956 957 #define NG_SEND_MSG_ID(error, here, msg, ID, retaddr) \ 958 do { \ 959 item_p item; \ 960 if ((item = ng_package_msg(msg)) == NULL) { \ 961 (msg) = NULL; \ 962 (error) = ENOMEM; \ 963 break; \ 964 } \ 965 if (((error) = ng_address_ID((here), (item), \ 966 (ID), (retaddr))) == 0) { \ 967 SAVE_LINE(item); \ 968 (error) = ng_snd_item((item), 0); \ 969 } \ 970 (msg) = NULL; \ 971 } while (0) 972 973 /* 974 * Redirect the message to the next hop using the given hook. 975 * ng_retarget_msg() frees the item if there is an error 976 * and returns an error code. It returns 0 on success. 977 */ 978 #define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr) \ 979 do { \ 980 if (((error) = ng_address_hook((here), (item), \ 981 (hook), (retaddr))) == 0) { \ 982 SAVE_LINE(item); \ 983 (error) = ng_snd_item((item), 0); \ 984 } \ 985 (item) = NULL; \ 986 } while (0) 987 988 /* 989 * Send a queue item back to it's originator with a response message. 990 * Assume original message was removed and freed separatly. 991 */ 992 #define NG_RESPOND_MSG(error, here, item, resp) \ 993 do { \ 994 if (resp) { \ 995 ng_ID_t dest = NGI_RETADDR(item); \ 996 NGI_RETADDR(item) = NULL; \ 997 NGI_MSG(item) = resp; \ 998 if ((ng_address_ID((here), (item), \ 999 dest, NULL )) == 0) { \ 1000 SAVE_LINE(item); \ 1001 (error) = ng_snd_item((item), 1); \ 1002 } else { \ 1003 (error) = EINVAL; \ 1004 } \ 1005 } else { \ 1006 NG_FREE_ITEM(item); \ 1007 } \ 1008 (item) = NULL; \ 1009 } while (0) 1010 1011 1012 /*********************************************************************** 1013 ******** Structures Definitions and Macros for defining a node ******* 1014 *********************************************************************** 1015 * 1016 * Here we define the structures needed to actually define a new node 1017 * type. 1018 */ 1019 1020 /* 1021 * Command list -- each node type specifies the command that it knows 1022 * how to convert between ASCII and binary using an array of these. 1023 * The last element in the array must be a terminator with cookie=0. 1024 */ 1025 1026 struct ng_cmdlist { 1027 u_int32_t cookie; /* command typecookie */ 1028 int cmd; /* command number */ 1029 const char *name; /* command name */ 1030 const struct ng_parse_type *mesgType; /* args if !NGF_RESP */ 1031 const struct ng_parse_type *respType; /* args if NGF_RESP */ 1032 }; 1033 1034 /* 1035 * Structure of a node type 1036 * If data is sent to the "rcvdata()" entrypoint then the system 1037 * may decide to defer it until later by queing it with the normal netgraph 1038 * input queuing system. This is decidde by the HK_QUEUE flag being set in 1039 * the flags word of the peer (receiving) hook. The dequeuing mechanism will 1040 * ensure it is not requeued again. 1041 * Note the input queueing system is to allow modules 1042 * to 'release the stack' or to pass data across spl layers. 1043 * The data will be redelivered as soon as the NETISR code runs 1044 * which may be almost immediatly. A node may also do it's own queueing 1045 * for other reasons (e.g. device output queuing). 1046 */ 1047 struct ng_type { 1048 1049 u_int32_t version; /* must equal NG_API_VERSION */ 1050 const char *name; /* Unique type name */ 1051 modeventhand_t mod_event; /* Module event handler (optional) */ 1052 ng_constructor_t *constructor; /* Node constructor */ 1053 ng_rcvmsg_t *rcvmsg; /* control messages come here */ 1054 ng_shutdown_t *shutdown; /* reset, and free resources */ 1055 ng_newhook_t *newhook; /* first notification of new hook */ 1056 ng_findhook_t *findhook; /* only if you have lots of hooks */ 1057 ng_connect_t *connect; /* final notification of new hook */ 1058 ng_rcvdata_t *rcvdata; /* data comes here */ 1059 ng_disconnect_t *disconnect; /* notify on disconnect */ 1060 1061 const struct ng_cmdlist *cmdlist; /* commands we can convert */ 1062 1063 /* R/W data private to the base netgraph code DON'T TOUCH! */ 1064 LIST_ENTRY(ng_type) types; /* linked list of all types */ 1065 int refs; /* number of instances */ 1066 }; 1067 1068 /* 1069 * Use the NETGRAPH_INIT() macro to link a node type into the 1070 * netgraph system. This works for types compiled into the kernel 1071 * as well as KLD modules. The first argument should be the type 1072 * name (eg, echo) and the second a pointer to the type struct. 1073 * 1074 * If a different link time is desired, e.g., a device driver that 1075 * needs to install its netgraph type before probing, use the 1076 * NETGRAPH_INIT_ORDERED() macro instead. Deivce drivers probably 1077 * want to use SI_SUB_DRIVERS instead of SI_SUB_PSEUDO. 1078 */ 1079 1080 #define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \ 1081 static moduledata_t ng_##typename##_mod = { \ 1082 "ng_" #typename, \ 1083 ng_mod_event, \ 1084 (typestructp) \ 1085 }; \ 1086 DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \ 1087 MODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \ 1088 NG_ABI_VERSION, \ 1089 NG_ABI_VERSION) 1090 1091 #define NETGRAPH_INIT(tn, tp) \ 1092 NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY) 1093 1094 /* Special malloc() type for netgraph structs and ctrl messages */ 1095 /* Only these two types should be visible to nodes */ 1096 MALLOC_DECLARE(M_NETGRAPH); 1097 MALLOC_DECLARE(M_NETGRAPH_MSG); 1098 MALLOC_DECLARE(M_NETGRAPH_META); 1099 1100 /* declare the base of the netgraph sysclt hierarchy */ 1101 /* but only if this file cares about sysctls */ 1102 #ifdef SYSCTL_DECL 1103 SYSCTL_DECL(_net_graph); 1104 #endif 1105 1106 /* 1107 * Methods that the nodes can use. 1108 * Many of these methods should usually NOT be used directly but via 1109 * Macros above. 1110 */ 1111 int ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr); 1112 int ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr); 1113 int ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr); 1114 meta_p ng_copy_meta(meta_p meta); 1115 hook_p ng_findhook(node_p node, const char *name); 1116 int ng_make_node_common(struct ng_type *typep, node_p *nodep); 1117 int ng_name_node(node_p node, const char *name); 1118 int ng_newtype(struct ng_type *tp); 1119 ng_ID_t ng_node2ID(node_p node); 1120 item_p ng_package_data(struct mbuf *m, meta_p meta); 1121 item_p ng_package_msg(struct ng_mesg *msg); 1122 item_p ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg); 1123 void ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr); 1124 int ng_rmhook_self(hook_p hook); /* if a node wants to kill a hook */ 1125 int ng_rmnode_self(node_p here); /* if a node wants to suicide */ 1126 int ng_rmtype(struct ng_type *tp); 1127 int ng_snd_item(item_p item, int queue); 1128 int ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, 1129 void *arg1, int arg2); 1130 1131 /* 1132 * prototypes the user should DEFINITLY not use directly 1133 */ 1134 void ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */ 1135 int ng_mod_event(module_t mod, int what, void *arg); 1136 1137 #endif /* _NETGRAPH_NETGRAPH_H_ */ 1138 1139