152419Sjulian/* 252419Sjulian * netgraph.h 3139823Simp */ 4139823Simp 5139823Simp/*- 652419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 752419Sjulian * All rights reserved. 852419Sjulian * 952419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 1052419Sjulian * redistribution of this software, in source or object code forms, with or 1152419Sjulian * without modifications are expressly permitted by Whistle Communications; 1252419Sjulian * provided, however, that: 1352419Sjulian * 1. Any and all reproductions of the source or object code must include the 1452419Sjulian * copyright notice above and the following disclaimer of warranties; and 1552419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1652419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1752419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1852419Sjulian * such appears in the above copyright notice or in the software. 1952419Sjulian * 2052419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 2152419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 2252419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 2352419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2452419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2552419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2652419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2752419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2852419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2952419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 3052419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 3152419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 3252419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 3352419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3452419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3552419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3652419Sjulian * OF SUCH DAMAGE. 3752419Sjulian * 3867506Sjulian * Author: Julian Elischer <julian@freebsd.org> 3952419Sjulian * 4052419Sjulian * $FreeBSD: releng/10.2/sys/netgraph/netgraph.h 231831 2012-02-16 19:10:01Z glebius $ 4152752Sjulian * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $ 4252419Sjulian */ 4352419Sjulian 4452419Sjulian#ifndef _NETGRAPH_NETGRAPH_H_ 45122481Sru#define _NETGRAPH_NETGRAPH_H_ 4652419Sjulian 4755205Speter#ifndef _KERNEL 4852419Sjulian#error "This file should not be included in user level programs" 4952419Sjulian#endif 5052419Sjulian 5170784Sjulian#include <sys/queue.h> 5274914Sjhb#include <sys/lock.h> 5370784Sjulian#include <sys/malloc.h> 5470784Sjulian#include <sys/module.h> 5570700Sjulian#include <sys/mutex.h> 56223754Sglebius#include <sys/refcount.h> 57146259Sglebius 58179973Sgnn#ifdef HAVE_KERNEL_OPTION_HEADERS 59146259Sglebius#include "opt_netgraph.h" 60226829Sglebius#include "opt_kdb.h" 61179973Sgnn#endif 62146259Sglebius 6370870Sjulian/* debugging options */ 6470870Sjulian#define NG_SEPARATE_MALLOC /* make modules use their own malloc types */ 6570784Sjulian 6670784Sjulian/* 6770784Sjulian * This defines the in-kernel binary interface version. 6870784Sjulian * It is possible to change this but leave the external message 6970784Sjulian * API the same. Each type also has it's own cookies for versioning as well. 7070784Sjulian * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug 7170784Sjulian * modules. 7270784Sjulian */ 73178228Smav#define _NG_ABI_VERSION 12 7470784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 7570784Sjulian#define NG_ABI_VERSION (_NG_ABI_VERSION + 0x10000) 7670784Sjulian#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 7770784Sjulian#define NG_ABI_VERSION _NG_ABI_VERSION 7870784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 7970784Sjulian 8070784Sjulian 8170784Sjulian/* 8270784Sjulian * Forward references for the basic structures so we can 8370784Sjulian * define the typedefs and use them in the structures themselves. 8470784Sjulian */ 8570784Sjulianstruct ng_hook ; 8670784Sjulianstruct ng_node ; 8770784Sjulianstruct ng_item ; 8870700Sjuliantypedef struct ng_item *item_p; 8970784Sjuliantypedef struct ng_node *node_p; 9070784Sjuliantypedef struct ng_hook *hook_p; 9170700Sjulian 9271885Sjulian/* node method definitions */ 9371885Sjuliantypedef int ng_constructor_t(node_p node); 94129836Sjuliantypedef int ng_close_t(node_p node); 9571885Sjuliantypedef int ng_shutdown_t(node_p node); 9671885Sjuliantypedef int ng_newhook_t(node_p node, hook_p hook, const char *name); 9771885Sjuliantypedef hook_p ng_findhook_t(node_p node, const char *name); 9871885Sjuliantypedef int ng_connect_t(hook_p hook); 9971885Sjuliantypedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook); 10071885Sjuliantypedef int ng_rcvdata_t(hook_p hook, item_p item); 10171885Sjuliantypedef int ng_disconnect_t(hook_p hook); 10271885Sjuliantypedef int ng_rcvitem (node_p node, hook_p hook, item_p item); 10371885Sjulian 10470784Sjulian/*********************************************************************** 10570784Sjulian ***************** Hook Structure and Methods ************************** 10670784Sjulian *********************************************************************** 10770784Sjulian * 10852419Sjulian * Structure of a hook 10952419Sjulian */ 11052419Sjulianstruct ng_hook { 111125021Sharti char hk_name[NG_HOOKSIZ]; /* what this node knows this link as */ 11270784Sjulian void *hk_private; /* node dependant ID for this hook */ 11370784Sjulian int hk_flags; /* info about this hook/link */ 114148238Sglebius int hk_type; /* tbd: hook data link type */ 11570784Sjulian struct ng_hook *hk_peer; /* the other end of this link */ 11670784Sjulian struct ng_node *hk_node; /* The node this hook is attached to */ 11770784Sjulian LIST_ENTRY(ng_hook) hk_hooks; /* linked list of all hooks on node */ 11871885Sjulian ng_rcvmsg_t *hk_rcvmsg; /* control messages come here */ 11971885Sjulian ng_rcvdata_t *hk_rcvdata; /* data comes here */ 120178228Smav int hk_refs; /* dont actually free this till 0 */ 12170784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 12270784Sjulian#define HK_MAGIC 0x78573011 12370784Sjulian int hk_magic; 12470784Sjulian char *lastfile; 12570784Sjulian int lastline; 12670784Sjulian SLIST_ENTRY(ng_hook) hk_all; /* all existing items */ 12770784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 12852419Sjulian}; 12952419Sjulian/* Flags for a hook */ 13052419Sjulian#define HK_INVALID 0x0001 /* don't trust it! */ 13169922Sjulian#define HK_QUEUE 0x0002 /* queue for later delivery */ 13270700Sjulian#define HK_FORCE_WRITER 0x0004 /* Incoming data queued as a writer */ 13370935Sjulian#define HK_DEAD 0x0008 /* This is the dead hook.. don't free */ 134175847Smav#define HK_HI_STACK 0x0010 /* Hook has hi stack usage */ 135194012Szec#define HK_TO_INBOUND 0x0020 /* Hook on ntw. stack inbound path. */ 13652419Sjulian 13752419Sjulian/* 13870784Sjulian * Public Methods for hook 13970784Sjulian * If you can't do it with these you probably shouldn;t be doing it. 14070784Sjulian */ 14170784Sjulianvoid ng_unref_hook(hook_p hook); /* don't move this */ 142223754Sglebius#define _NG_HOOK_REF(hook) refcount_acquire(&(hook)->hk_refs) 14370784Sjulian#define _NG_HOOK_NAME(hook) ((hook)->hk_name) 14470784Sjulian#define _NG_HOOK_UNREF(hook) ng_unref_hook(hook) 14570784Sjulian#define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0) 14671885Sjulian#define _NG_HOOK_SET_RCVMSG(hook, val) do {(hook)->hk_rcvmsg = val;} while (0) 14771885Sjulian#define _NG_HOOK_SET_RCVDATA(hook, val) do {(hook)->hk_rcvdata = val;} while (0) 14870784Sjulian#define _NG_HOOK_PRIVATE(hook) ((hook)->hk_private) 14970784Sjulian#define _NG_HOOK_NOT_VALID(hook) ((hook)->hk_flags & HK_INVALID) 15073370Sjulian#define _NG_HOOK_IS_VALID(hook) (!((hook)->hk_flags & HK_INVALID)) 15170784Sjulian#define _NG_HOOK_NODE(hook) ((hook)->hk_node) /* only rvalue! */ 15270784Sjulian#define _NG_HOOK_PEER(hook) ((hook)->hk_peer) /* only rvalue! */ 15370784Sjulian#define _NG_HOOK_FORCE_WRITER(hook) \ 15470784Sjulian do { hook->hk_flags |= HK_FORCE_WRITER; } while (0) 15570784Sjulian#define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0) 156194012Szec#define _NG_HOOK_SET_TO_INBOUND(hook) \ 157194012Szec do { hook->hk_flags |= HK_TO_INBOUND; } while (0) 158175847Smav#define _NG_HOOK_HI_STACK(hook) do { hook->hk_flags |= HK_HI_STACK; } while (0) 15970784Sjulian 16070784Sjulian/* Some shortcuts */ 16170784Sjulian#define NG_PEER_NODE(hook) NG_HOOK_NODE(NG_HOOK_PEER(hook)) 16270784Sjulian#define NG_PEER_HOOK_NAME(hook) NG_HOOK_NAME(NG_HOOK_PEER(hook)) 16370784Sjulian#define NG_PEER_NODE_NAME(hook) NG_NODE_NAME(NG_PEER_NODE(hook)) 16470784Sjulian 16570784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 16670784Sjulian#define _NN_ __FILE__,__LINE__ 16770784Sjulianvoid dumphook (hook_p hook, char *file, int line); 16870784Sjulianstatic __inline void _chkhook(hook_p hook, char *file, int line); 16970784Sjulianstatic __inline void _ng_hook_ref(hook_p hook, char * file, int line); 17070784Sjulianstatic __inline char * _ng_hook_name(hook_p hook, char * file, int line); 17170784Sjulianstatic __inline void _ng_hook_unref(hook_p hook, char * file, int line); 17270784Sjulianstatic __inline void _ng_hook_set_private(hook_p hook, 17371885Sjulian void * val, char * file, int line); 17471885Sjulianstatic __inline void _ng_hook_set_rcvmsg(hook_p hook, 17571885Sjulian ng_rcvmsg_t *val, char * file, int line); 17671885Sjulianstatic __inline void _ng_hook_set_rcvdata(hook_p hook, 17771885Sjulian ng_rcvdata_t *val, char * file, int line); 17870784Sjulianstatic __inline void * _ng_hook_private(hook_p hook, char * file, int line); 17970784Sjulianstatic __inline int _ng_hook_not_valid(hook_p hook, char * file, int line); 18070784Sjulianstatic __inline int _ng_hook_is_valid(hook_p hook, char * file, int line); 18170784Sjulianstatic __inline node_p _ng_hook_node(hook_p hook, char * file, int line); 18270784Sjulianstatic __inline hook_p _ng_hook_peer(hook_p hook, char * file, int line); 18370784Sjulianstatic __inline void _ng_hook_force_writer(hook_p hook, char * file, 184194012Szec int line); 185194012Szecstatic __inline void _ng_hook_force_queue(hook_p hook, char * file, 186194012Szec int line); 187194012Szecstatic __inline void _ng_hook_set_to_inbound(hook_p hook, char * file, 188194012Szec int line); 18970784Sjulian 190148870Sjulianstatic __inline void 19170784Sjulian_chkhook(hook_p hook, char *file, int line) 19270784Sjulian{ 19370784Sjulian if (hook->hk_magic != HK_MAGIC) { 194226829Sglebius printf("Accessing freed "); 19570784Sjulian dumphook(hook, file, line); 19670784Sjulian } 19770784Sjulian hook->lastline = line; 19870784Sjulian hook->lastfile = file; 19970784Sjulian} 20070784Sjulian 20170784Sjulianstatic __inline void 20270784Sjulian_ng_hook_ref(hook_p hook, char * file, int line) 20370784Sjulian{ 20470784Sjulian _chkhook(hook, file, line); 20570784Sjulian _NG_HOOK_REF(hook); 206152451Sglebius} 20770784Sjulian 20870784Sjulianstatic __inline char * 20970784Sjulian_ng_hook_name(hook_p hook, char * file, int line) 21070784Sjulian{ 21170784Sjulian _chkhook(hook, file, line); 21270784Sjulian return (_NG_HOOK_NAME(hook)); 213152451Sglebius} 21470784Sjulian 21570784Sjulianstatic __inline void 21670784Sjulian_ng_hook_unref(hook_p hook, char * file, int line) 21770784Sjulian{ 21870784Sjulian _chkhook(hook, file, line); 21970784Sjulian _NG_HOOK_UNREF(hook); 220152451Sglebius} 22170784Sjulian 22270784Sjulianstatic __inline void 22370784Sjulian_ng_hook_set_private(hook_p hook, void *val, char * file, int line) 22470784Sjulian{ 22570784Sjulian _chkhook(hook, file, line); 22670784Sjulian _NG_HOOK_SET_PRIVATE(hook, val); 227152451Sglebius} 22870784Sjulian 22971885Sjulianstatic __inline void 23071885Sjulian_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line) 23171885Sjulian{ 23271885Sjulian _chkhook(hook, file, line); 23371885Sjulian _NG_HOOK_SET_RCVMSG(hook, val); 234152451Sglebius} 23571885Sjulian 23671885Sjulianstatic __inline void 23771885Sjulian_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line) 23871885Sjulian{ 23971885Sjulian _chkhook(hook, file, line); 24071885Sjulian _NG_HOOK_SET_RCVDATA(hook, val); 241152451Sglebius} 24271885Sjulian 24370784Sjulianstatic __inline void * 24470784Sjulian_ng_hook_private(hook_p hook, char * file, int line) 24570784Sjulian{ 24670784Sjulian _chkhook(hook, file, line); 24770784Sjulian return (_NG_HOOK_PRIVATE(hook)); 248152451Sglebius} 24970784Sjulian 25070784Sjulianstatic __inline int 25170784Sjulian_ng_hook_not_valid(hook_p hook, char * file, int line) 25270784Sjulian{ 25370784Sjulian _chkhook(hook, file, line); 25470784Sjulian return (_NG_HOOK_NOT_VALID(hook)); 255152451Sglebius} 25670784Sjulian 25770784Sjulianstatic __inline int 25870784Sjulian_ng_hook_is_valid(hook_p hook, char * file, int line) 25970784Sjulian{ 26070784Sjulian _chkhook(hook, file, line); 26170784Sjulian return (_NG_HOOK_IS_VALID(hook)); 262152451Sglebius} 26370784Sjulian 26470784Sjulianstatic __inline node_p 26570784Sjulian_ng_hook_node(hook_p hook, char * file, int line) 26670784Sjulian{ 26770784Sjulian _chkhook(hook, file, line); 26870784Sjulian return (_NG_HOOK_NODE(hook)); 269152451Sglebius} 27070784Sjulian 27170784Sjulianstatic __inline hook_p 27270784Sjulian_ng_hook_peer(hook_p hook, char * file, int line) 27370784Sjulian{ 27470784Sjulian _chkhook(hook, file, line); 27570784Sjulian return (_NG_HOOK_PEER(hook)); 276152451Sglebius} 27770784Sjulian 27870784Sjulianstatic __inline void 27970784Sjulian_ng_hook_force_writer(hook_p hook, char * file, int line) 28070784Sjulian{ 28170784Sjulian _chkhook(hook, file, line); 28270784Sjulian _NG_HOOK_FORCE_WRITER(hook); 283152451Sglebius} 28470784Sjulian 28570784Sjulianstatic __inline void 28670784Sjulian_ng_hook_force_queue(hook_p hook, char * file, int line) 28770784Sjulian{ 28870784Sjulian _chkhook(hook, file, line); 28970784Sjulian _NG_HOOK_FORCE_QUEUE(hook); 290152451Sglebius} 29170784Sjulian 292175847Smavstatic __inline void 293194012Szec_ng_hook_set_to_inbound(hook_p hook, char * file, int line) 294194012Szec{ 295194012Szec _chkhook(hook, file, line); 296194012Szec _NG_HOOK_SET_TO_INBOUND(hook); 297194012Szec} 298194012Szec 299194012Szecstatic __inline void 300175847Smav_ng_hook_hi_stack(hook_p hook, char * file, int line) 301175847Smav{ 302175847Smav _chkhook(hook, file, line); 303175847Smav _NG_HOOK_HI_STACK(hook); 304175847Smav} 30570784Sjulian 306175847Smav 30770784Sjulian#define NG_HOOK_REF(hook) _ng_hook_ref(hook, _NN_) 30870784Sjulian#define NG_HOOK_NAME(hook) _ng_hook_name(hook, _NN_) 30970784Sjulian#define NG_HOOK_UNREF(hook) _ng_hook_unref(hook, _NN_) 31070784Sjulian#define NG_HOOK_SET_PRIVATE(hook, val) _ng_hook_set_private(hook, val, _NN_) 31171885Sjulian#define NG_HOOK_SET_RCVMSG(hook, val) _ng_hook_set_rcvmsg(hook, val, _NN_) 31271885Sjulian#define NG_HOOK_SET_RCVDATA(hook, val) _ng_hook_set_rcvdata(hook, val, _NN_) 31370784Sjulian#define NG_HOOK_PRIVATE(hook) _ng_hook_private(hook, _NN_) 31470784Sjulian#define NG_HOOK_NOT_VALID(hook) _ng_hook_not_valid(hook, _NN_) 31570784Sjulian#define NG_HOOK_IS_VALID(hook) _ng_hook_is_valid(hook, _NN_) 31670784Sjulian#define NG_HOOK_NODE(hook) _ng_hook_node(hook, _NN_) 31770784Sjulian#define NG_HOOK_PEER(hook) _ng_hook_peer(hook, _NN_) 31870784Sjulian#define NG_HOOK_FORCE_WRITER(hook) _ng_hook_force_writer(hook, _NN_) 31970784Sjulian#define NG_HOOK_FORCE_QUEUE(hook) _ng_hook_force_queue(hook, _NN_) 320194012Szec#define NG_HOOK_SET_TO_INBOUND(hook) _ng_hook_set_to_inbound(hook, _NN_) 321175847Smav#define NG_HOOK_HI_STACK(hook) _ng_hook_hi_stack(hook, _NN_) 32270784Sjulian 32370784Sjulian#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 32470784Sjulian 32570784Sjulian#define NG_HOOK_REF(hook) _NG_HOOK_REF(hook) 32670784Sjulian#define NG_HOOK_NAME(hook) _NG_HOOK_NAME(hook) 32770784Sjulian#define NG_HOOK_UNREF(hook) _NG_HOOK_UNREF(hook) 32870784Sjulian#define NG_HOOK_SET_PRIVATE(hook, val) _NG_HOOK_SET_PRIVATE(hook, val) 32971885Sjulian#define NG_HOOK_SET_RCVMSG(hook, val) _NG_HOOK_SET_RCVMSG(hook, val) 33071885Sjulian#define NG_HOOK_SET_RCVDATA(hook, val) _NG_HOOK_SET_RCVDATA(hook, val) 33170784Sjulian#define NG_HOOK_PRIVATE(hook) _NG_HOOK_PRIVATE(hook) 33270784Sjulian#define NG_HOOK_NOT_VALID(hook) _NG_HOOK_NOT_VALID(hook) 33370784Sjulian#define NG_HOOK_IS_VALID(hook) _NG_HOOK_IS_VALID(hook) 33470784Sjulian#define NG_HOOK_NODE(hook) _NG_HOOK_NODE(hook) 33570784Sjulian#define NG_HOOK_PEER(hook) _NG_HOOK_PEER(hook) 33670784Sjulian#define NG_HOOK_FORCE_WRITER(hook) _NG_HOOK_FORCE_WRITER(hook) 33770784Sjulian#define NG_HOOK_FORCE_QUEUE(hook) _NG_HOOK_FORCE_QUEUE(hook) 338194012Szec#define NG_HOOK_SET_TO_INBOUND(hook) _NG_HOOK_SET_TO_INBOUND(hook) 339175847Smav#define NG_HOOK_HI_STACK(hook) _NG_HOOK_HI_STACK(hook) 34070784Sjulian 34170784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 34270784Sjulian 34370784Sjulian/*********************************************************************** 34470784Sjulian ***************** Node Structure and Methods ************************** 34570784Sjulian *********************************************************************** 34652419Sjulian * Structure of a node 34770784Sjulian * including the eembedded queue structure. 34870784Sjulian * 349152451Sglebius * The structure for queueing Netgraph request items 35070784Sjulian * embedded in the node structure 35152419Sjulian */ 35270784Sjulianstruct ng_queue { 353178228Smav u_int q_flags; /* Current r/w/q lock flags */ 354178228Smav u_int q_flags2; /* Other queue flags */ 355152451Sglebius struct mtx q_mtx; 356178228Smav STAILQ_ENTRY(ng_node) q_work; /* nodes with work to do */ 357178228Smav STAILQ_HEAD(, ng_item) queue; /* actually items queue */ 35870784Sjulian}; 35970784Sjulian 36052419Sjulianstruct ng_node { 361125021Sharti char nd_name[NG_NODESIZ]; /* optional globally unique name */ 36270784Sjulian struct ng_type *nd_type; /* the installed 'type' */ 36370784Sjulian int nd_flags; /* see below for bit definitions */ 36470784Sjulian int nd_numhooks; /* number of hooks */ 36570784Sjulian void *nd_private; /* node type dependant node ID */ 36670784Sjulian ng_ID_t nd_ID; /* Unique per node */ 36770784Sjulian LIST_HEAD(hooks, ng_hook) nd_hooks; /* linked list of node hooks */ 368231831Sglebius LIST_ENTRY(ng_node) nd_nodes; /* name hash collision list */ 36970784Sjulian LIST_ENTRY(ng_node) nd_idnodes; /* ID hash collision list */ 37070784Sjulian struct ng_queue nd_input_queue; /* input queue for locking */ 371178228Smav int nd_refs; /* # of references to this node */ 372191816Szec struct vnet *nd_vnet; /* network stack instance */ 37370784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 37470784Sjulian#define ND_MAGIC 0x59264837 37570784Sjulian int nd_magic; 37670784Sjulian char *lastfile; 37770784Sjulian int lastline; 37870784Sjulian SLIST_ENTRY(ng_node) nd_all; /* all existing nodes */ 37970784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 38052419Sjulian}; 38152419Sjulian 38252419Sjulian/* Flags for a node */ 383132464Sjulian#define NGF_INVALID 0x00000001 /* free when refs go to 0 */ 384132464Sjulian#define NG_INVALID NGF_INVALID /* compat for old code */ 385132464Sjulian#define NGF_FORCE_WRITER 0x00000004 /* Never multithread this node */ 386132464Sjulian#define NG_FORCE_WRITER NGF_FORCE_WRITER /* compat for old code */ 387132464Sjulian#define NGF_CLOSING 0x00000008 /* ng_rmnode() at work */ 388132464Sjulian#define NG_CLOSING NGF_CLOSING /* compat for old code */ 389132464Sjulian#define NGF_REALLY_DIE 0x00000010 /* "persistent" node is unloading */ 390132464Sjulian#define NG_REALLY_DIE NGF_REALLY_DIE /* compat for old code */ 391175847Smav#define NGF_HI_STACK 0x00000020 /* node has hi stack usage */ 39252419Sjulian#define NGF_TYPE1 0x10000000 /* reserved for type specific storage */ 39352419Sjulian#define NGF_TYPE2 0x20000000 /* reserved for type specific storage */ 39452419Sjulian#define NGF_TYPE3 0x40000000 /* reserved for type specific storage */ 39552419Sjulian#define NGF_TYPE4 0x80000000 /* reserved for type specific storage */ 39652419Sjulian 39752419Sjulian/* 39870784Sjulian * Public methods for nodes. 39970784Sjulian * If you can't do it with these you probably shouldn't be doing it. 40070784Sjulian */ 401223754Sglebiusvoid ng_unref_node(node_p node); /* don't move this */ 40270784Sjulian#define _NG_NODE_NAME(node) ((node)->nd_name + 0) 40370784Sjulian#define _NG_NODE_HAS_NAME(node) ((node)->nd_name[0] + 0) 40470784Sjulian#define _NG_NODE_ID(node) ((node)->nd_ID + 0) 405223754Sglebius#define _NG_NODE_REF(node) refcount_acquire(&(node)->nd_refs) 40670784Sjulian#define _NG_NODE_UNREF(node) ng_unref_node(node) 40770784Sjulian#define _NG_NODE_SET_PRIVATE(node, val) do {(node)->nd_private = val;} while (0) 40870784Sjulian#define _NG_NODE_PRIVATE(node) ((node)->nd_private) 409132464Sjulian#define _NG_NODE_IS_VALID(node) (!((node)->nd_flags & NGF_INVALID)) 410132464Sjulian#define _NG_NODE_NOT_VALID(node) ((node)->nd_flags & NGF_INVALID) 41170784Sjulian#define _NG_NODE_NUMHOOKS(node) ((node)->nd_numhooks + 0) /* rvalue */ 41270784Sjulian#define _NG_NODE_FORCE_WRITER(node) \ 413132464Sjulian do{ node->nd_flags |= NGF_FORCE_WRITER; }while (0) 414175847Smav#define _NG_NODE_HI_STACK(node) \ 415175847Smav do{ node->nd_flags |= NGF_HI_STACK; }while (0) 41671849Sjulian#define _NG_NODE_REALLY_DIE(node) \ 417132464Sjulian do{ node->nd_flags |= (NGF_REALLY_DIE|NGF_INVALID); }while (0) 418132464Sjulian#define _NG_NODE_REVIVE(node) \ 419132464Sjulian do { node->nd_flags &= ~NGF_INVALID; } while (0) 42070784Sjulian/* 42170784Sjulian * The hook iterator. 42270784Sjulian * This macro will call a function of type ng_fn_eachhook for each 42370784Sjulian * hook attached to the node. If the function returns 0, then the 42470784Sjulian * iterator will stop and return a pointer to the hook that returned 0. 42570784Sjulian */ 42670784Sjuliantypedef int ng_fn_eachhook(hook_p hook, void* arg); 42770784Sjulian#define _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 42870784Sjulian do { \ 429102190Sarchie hook_p _hook; \ 430102190Sarchie (rethook) = NULL; \ 431102190Sarchie LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) { \ 432102190Sarchie if ((fn)(_hook, arg) == 0) { \ 433102190Sarchie (rethook) = _hook; \ 43470784Sjulian break; \ 43570784Sjulian } \ 43670784Sjulian } \ 43770784Sjulian } while (0) 43870784Sjulian 43970784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 44070784Sjulianvoid dumpnode(node_p node, char *file, int line); 441148870Sjulianstatic __inline void _chknode(node_p node, char *file, int line); 44270784Sjulianstatic __inline char * _ng_node_name(node_p node, char *file, int line); 44370784Sjulianstatic __inline int _ng_node_has_name(node_p node, char *file, int line); 44470784Sjulianstatic __inline ng_ID_t _ng_node_id(node_p node, char *file, int line); 44570784Sjulianstatic __inline void _ng_node_ref(node_p node, char *file, int line); 446223768Sglebiusstatic __inline void _ng_node_unref(node_p node, char *file, int line); 44770784Sjulianstatic __inline void _ng_node_set_private(node_p node, void * val, 44870784Sjulian char *file, int line); 44970784Sjulianstatic __inline void * _ng_node_private(node_p node, char *file, int line); 45070784Sjulianstatic __inline int _ng_node_is_valid(node_p node, char *file, int line); 45170784Sjulianstatic __inline int _ng_node_not_valid(node_p node, char *file, int line); 45270784Sjulianstatic __inline int _ng_node_numhooks(node_p node, char *file, int line); 45370784Sjulianstatic __inline void _ng_node_force_writer(node_p node, char *file, int line); 45470784Sjulianstatic __inline hook_p _ng_node_foreach_hook(node_p node, 45570784Sjulian ng_fn_eachhook *fn, void *arg, char *file, int line); 456132464Sjulianstatic __inline void _ng_node_revive(node_p node, char *file, int line); 45770784Sjulian 458152451Sglebiusstatic __inline void 45970784Sjulian_chknode(node_p node, char *file, int line) 46070784Sjulian{ 46170784Sjulian if (node->nd_magic != ND_MAGIC) { 462226829Sglebius printf("Accessing freed "); 46370784Sjulian dumpnode(node, file, line); 46470784Sjulian } 46570784Sjulian node->lastline = line; 46670784Sjulian node->lastfile = file; 46770784Sjulian} 46870784Sjulian 46970784Sjulianstatic __inline char * 47070784Sjulian_ng_node_name(node_p node, char *file, int line) 47170784Sjulian{ 47270784Sjulian _chknode(node, file, line); 47370784Sjulian return(_NG_NODE_NAME(node)); 47470784Sjulian} 47570784Sjulian 476152451Sglebiusstatic __inline int 47770784Sjulian_ng_node_has_name(node_p node, char *file, int line) 47870784Sjulian{ 47970784Sjulian _chknode(node, file, line); 48070784Sjulian return(_NG_NODE_HAS_NAME(node)); 48170784Sjulian} 48270784Sjulian 48370784Sjulianstatic __inline ng_ID_t 48470784Sjulian_ng_node_id(node_p node, char *file, int line) 48570784Sjulian{ 48670784Sjulian _chknode(node, file, line); 48770784Sjulian return(_NG_NODE_ID(node)); 48870784Sjulian} 48970784Sjulian 490152451Sglebiusstatic __inline void 49170784Sjulian_ng_node_ref(node_p node, char *file, int line) 49270784Sjulian{ 49370784Sjulian _chknode(node, file, line); 494154270Sglebius _NG_NODE_REF(node); 49570784Sjulian} 49670784Sjulian 497223761Sglebiusstatic __inline void 49870784Sjulian_ng_node_unref(node_p node, char *file, int line) 49970784Sjulian{ 50070784Sjulian _chknode(node, file, line); 501223761Sglebius _NG_NODE_UNREF(node); 50270784Sjulian} 50370784Sjulian 50470784Sjulianstatic __inline void 50570784Sjulian_ng_node_set_private(node_p node, void * val, char *file, int line) 50670784Sjulian{ 50770784Sjulian _chknode(node, file, line); 50870784Sjulian _NG_NODE_SET_PRIVATE(node, val); 50970784Sjulian} 51070784Sjulian 51170784Sjulianstatic __inline void * 51270784Sjulian_ng_node_private(node_p node, char *file, int line) 51370784Sjulian{ 51470784Sjulian _chknode(node, file, line); 51570784Sjulian return (_NG_NODE_PRIVATE(node)); 51670784Sjulian} 51770784Sjulian 51870784Sjulianstatic __inline int 51970784Sjulian_ng_node_is_valid(node_p node, char *file, int line) 52070784Sjulian{ 52170784Sjulian _chknode(node, file, line); 52270784Sjulian return(_NG_NODE_IS_VALID(node)); 52370784Sjulian} 52470784Sjulian 52570784Sjulianstatic __inline int 52670784Sjulian_ng_node_not_valid(node_p node, char *file, int line) 52770784Sjulian{ 52870784Sjulian _chknode(node, file, line); 52970784Sjulian return(_NG_NODE_NOT_VALID(node)); 53070784Sjulian} 53170784Sjulian 53270784Sjulianstatic __inline int 53370784Sjulian_ng_node_numhooks(node_p node, char *file, int line) 53470784Sjulian{ 53570784Sjulian _chknode(node, file, line); 53670784Sjulian return(_NG_NODE_NUMHOOKS(node)); 53770784Sjulian} 53870784Sjulian 53970784Sjulianstatic __inline void 54070784Sjulian_ng_node_force_writer(node_p node, char *file, int line) 54170784Sjulian{ 54270784Sjulian _chknode(node, file, line); 54370784Sjulian _NG_NODE_FORCE_WRITER(node); 54470784Sjulian} 54570784Sjulian 54671849Sjulianstatic __inline void 547175847Smav_ng_node_hi_stack(node_p node, char *file, int line) 548175847Smav{ 549175847Smav _chknode(node, file, line); 550175847Smav _NG_NODE_HI_STACK(node); 551175847Smav} 552175847Smav 553175847Smavstatic __inline void 55471849Sjulian_ng_node_really_die(node_p node, char *file, int line) 55571849Sjulian{ 55671849Sjulian _chknode(node, file, line); 55771849Sjulian _NG_NODE_REALLY_DIE(node); 55871849Sjulian} 55971849Sjulian 560132464Sjulianstatic __inline void 561132464Sjulian_ng_node_revive(node_p node, char *file, int line) 562132464Sjulian{ 563132464Sjulian _chknode(node, file, line); 564132464Sjulian _NG_NODE_REVIVE(node); 565132464Sjulian} 566132464Sjulian 56770784Sjulianstatic __inline hook_p 56870784Sjulian_ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg, 56970784Sjulian char *file, int line) 57070784Sjulian{ 57170784Sjulian hook_p hook; 57270784Sjulian _chknode(node, file, line); 57370784Sjulian _NG_NODE_FOREACH_HOOK(node, fn, arg, hook); 57470784Sjulian return (hook); 57570784Sjulian} 57670784Sjulian 57770784Sjulian#define NG_NODE_NAME(node) _ng_node_name(node, _NN_) 57870784Sjulian#define NG_NODE_HAS_NAME(node) _ng_node_has_name(node, _NN_) 57970917Sarchie#define NG_NODE_ID(node) _ng_node_id(node, _NN_) 58070784Sjulian#define NG_NODE_REF(node) _ng_node_ref(node, _NN_) 58170784Sjulian#define NG_NODE_UNREF(node) _ng_node_unref(node, _NN_) 58270784Sjulian#define NG_NODE_SET_PRIVATE(node, val) _ng_node_set_private(node, val, _NN_) 58370784Sjulian#define NG_NODE_PRIVATE(node) _ng_node_private(node, _NN_) 58470784Sjulian#define NG_NODE_IS_VALID(node) _ng_node_is_valid(node, _NN_) 58570784Sjulian#define NG_NODE_NOT_VALID(node) _ng_node_not_valid(node, _NN_) 58670784Sjulian#define NG_NODE_FORCE_WRITER(node) _ng_node_force_writer(node, _NN_) 587175847Smav#define NG_NODE_HI_STACK(node) _ng_node_hi_stack(node, _NN_) 58871849Sjulian#define NG_NODE_REALLY_DIE(node) _ng_node_really_die(node, _NN_) 58970784Sjulian#define NG_NODE_NUMHOOKS(node) _ng_node_numhooks(node, _NN_) 590132464Sjulian#define NG_NODE_REVIVE(node) _ng_node_revive(node, _NN_) 59170784Sjulian#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 59270784Sjulian do { \ 59370784Sjulian rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \ 59470784Sjulian } while (0) 59570784Sjulian 59670784Sjulian#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 59770784Sjulian 59870784Sjulian#define NG_NODE_NAME(node) _NG_NODE_NAME(node) 59970784Sjulian#define NG_NODE_HAS_NAME(node) _NG_NODE_HAS_NAME(node) 60070784Sjulian#define NG_NODE_ID(node) _NG_NODE_ID(node) 60170784Sjulian#define NG_NODE_REF(node) _NG_NODE_REF(node) 60270784Sjulian#define NG_NODE_UNREF(node) _NG_NODE_UNREF(node) 60370784Sjulian#define NG_NODE_SET_PRIVATE(node, val) _NG_NODE_SET_PRIVATE(node, val) 60470784Sjulian#define NG_NODE_PRIVATE(node) _NG_NODE_PRIVATE(node) 60570784Sjulian#define NG_NODE_IS_VALID(node) _NG_NODE_IS_VALID(node) 60670784Sjulian#define NG_NODE_NOT_VALID(node) _NG_NODE_NOT_VALID(node) 60770784Sjulian#define NG_NODE_FORCE_WRITER(node) _NG_NODE_FORCE_WRITER(node) 608175847Smav#define NG_NODE_HI_STACK(node) _NG_NODE_HI_STACK(node) 60971849Sjulian#define NG_NODE_REALLY_DIE(node) _NG_NODE_REALLY_DIE(node) 61070784Sjulian#define NG_NODE_NUMHOOKS(node) _NG_NODE_NUMHOOKS(node) 611132464Sjulian#define NG_NODE_REVIVE(node) _NG_NODE_REVIVE(node) 61270784Sjulian#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 61370784Sjulian _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) 61470784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 61570784Sjulian 61670784Sjulian/*********************************************************************** 61770784Sjulian ************* Node Queue and Item Structures and Methods ************** 61870784Sjulian *********************************************************************** 61970784Sjulian * 62053913Sarchie */ 62171849Sjuliantypedef void ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2); 622172806Smavtypedef int ng_item_fn2(node_p node, struct ng_item *item, hook_p hook); 623147774Sglebiustypedef void ng_apply_t(void *context, int error); 624172806Smavstruct ng_apply_info { 625172806Smav ng_apply_t *apply; 626172806Smav void *context; 627172806Smav int refs; 628177071Smav int error; 629172806Smav}; 63070700Sjulianstruct ng_item { 63170700Sjulian u_long el_flags; 632178228Smav STAILQ_ENTRY(ng_item) el_next; 63370700Sjulian node_p el_dest; /* The node it will be applied against (or NULL) */ 63470700Sjulian hook_p el_hook; /* Entering hook. Optional in Control messages */ 63570700Sjulian union { 636131374Sjulian struct mbuf *da_m; 63770700Sjulian struct { 63870700Sjulian struct ng_mesg *msg_msg; 63970700Sjulian ng_ID_t msg_retaddr; 64070700Sjulian } msg; 64171047Sjulian struct { 642172806Smav union { 643172806Smav ng_item_fn *fn_fn; 644172806Smav ng_item_fn2 *fn_fn2; 645172806Smav } fn_fn; 64671047Sjulian void *fn_arg1; 64771047Sjulian int fn_arg2; 64871047Sjulian } fn; 64970700Sjulian } body; 650147774Sglebius /* 651147774Sglebius * Optional callback called when item is being applied, 652147774Sglebius * and its context. 653147774Sglebius */ 654172806Smav struct ng_apply_info *apply; 655178228Smav u_int depth; 65670784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 65770700Sjulian char *lastfile; 65870700Sjulian int lastline; 65970700Sjulian TAILQ_ENTRY(ng_item) all; /* all existing items */ 66070784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 66170700Sjulian}; 66271047Sjulian 66371047Sjulian#define NGQF_TYPE 0x03 /* MASK of content definition */ 66471047Sjulian#define NGQF_MESG 0x00 /* the queue element is a message */ 66570700Sjulian#define NGQF_DATA 0x01 /* the queue element is data */ 66671047Sjulian#define NGQF_FN 0x02 /* the queue element is a function */ 667172806Smav#define NGQF_FN2 0x03 /* the queue element is a new function */ 66871047Sjulian 669151973Sglebius#define NGQF_RW 0x04 /* MASK for wanted queue mode */ 670151973Sglebius#define NGQF_READER 0x04 /* wants to be a reader */ 671151973Sglebius#define NGQF_WRITER 0x00 /* wants to be a writer */ 67270700Sjulian 673151973Sglebius#define NGQF_QMODE 0x08 /* MASK for how it was queued */ 674151973Sglebius#define NGQF_QREADER 0x08 /* was queued as a reader */ 675151973Sglebius#define NGQF_QWRITER 0x00 /* was queued as a writer */ 676151973Sglebius 67770159Sjulian/* 67870700Sjulian * Get the mbuf (etc) out of an item. 67970700Sjulian * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM() 68070700Sjulian * with it, (to avoid freeing the things twice). 68170700Sjulian * If you don't want to zero out the item then realise that the 68270700Sjulian * item still owns it. 68370700Sjulian * Retaddr is different. There are no references on that. It's just a number. 68470700Sjulian * The debug versions must be either all used everywhere or not at all. 68570700Sjulian */ 68670700Sjulian 687131374Sjulian#define _NGI_M(i) ((i)->body.da_m) 68870700Sjulian#define _NGI_MSG(i) ((i)->body.msg.msg_msg) 68970700Sjulian#define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr) 690172806Smav#define _NGI_FN(i) ((i)->body.fn.fn_fn.fn_fn) 691172806Smav#define _NGI_FN2(i) ((i)->body.fn.fn_fn.fn_fn2) 69271047Sjulian#define _NGI_ARG1(i) ((i)->body.fn.fn_arg1) 69371047Sjulian#define _NGI_ARG2(i) ((i)->body.fn.fn_arg2) 69471849Sjulian#define _NGI_NODE(i) ((i)->el_dest) 69571849Sjulian#define _NGI_HOOK(i) ((i)->el_hook) 69671849Sjulian#define _NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0) 69771849Sjulian#define _NGI_CLR_HOOK(i) do { \ 698102190Sarchie hook_p _hook = _NGI_HOOK(i); \ 699102190Sarchie if (_hook) { \ 700102190Sarchie _NG_HOOK_UNREF(_hook); \ 70171849Sjulian _NGI_HOOK(i) = NULL; \ 70271849Sjulian } \ 70371849Sjulian } while (0) 70471849Sjulian#define _NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0) 70571849Sjulian#define _NGI_CLR_NODE(i) do { \ 706102190Sarchie node_p _node = _NGI_NODE(i); \ 707102190Sarchie if (_node) { \ 708102190Sarchie _NG_NODE_UNREF(_node); \ 70971849Sjulian _NGI_NODE(i) = NULL; \ 71071849Sjulian } \ 71171849Sjulian } while (0) 71270700Sjulian 71370784Sjulian#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 71470784Sjulianvoid dumpitem(item_p item, char *file, int line); 71570784Sjulianstatic __inline void _ngi_check(item_p item, char *file, int line) ; 71670784Sjulianstatic __inline struct mbuf ** _ngi_m(item_p item, char *file, int line) ; 71771849Sjulianstatic __inline ng_ID_t * _ngi_retaddr(item_p item, char *file, int line); 71871849Sjulianstatic __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ; 71971849Sjulianstatic __inline ng_item_fn ** _ngi_fn(item_p item, char *file, int line) ; 720172806Smavstatic __inline ng_item_fn2 ** _ngi_fn2(item_p item, char *file, int line) ; 72171849Sjulianstatic __inline void ** _ngi_arg1(item_p item, char *file, int line) ; 72271849Sjulianstatic __inline int * _ngi_arg2(item_p item, char *file, int line) ; 72371849Sjulianstatic __inline node_p _ngi_node(item_p item, char *file, int line); 72471849Sjulianstatic __inline hook_p _ngi_hook(item_p item, char *file, int line); 72570700Sjulian 72670700Sjulianstatic __inline void 727152451Sglebius_ngi_check(item_p item, char *file, int line) 72870700Sjulian{ 72970700Sjulian (item)->lastline = line; 73070700Sjulian (item)->lastfile = file; 73170700Sjulian} 73270700Sjulian 73370700Sjulianstatic __inline struct mbuf ** 734152451Sglebius_ngi_m(item_p item, char *file, int line) 73570700Sjulian{ 73670700Sjulian _ngi_check(item, file, line); 73770700Sjulian return (&_NGI_M(item)); 73870700Sjulian} 73970700Sjulian 74070700Sjulianstatic __inline struct ng_mesg ** 741152451Sglebius_ngi_msg(item_p item, char *file, int line) 74270700Sjulian{ 74370700Sjulian _ngi_check(item, file, line); 74470700Sjulian return (&_NGI_MSG(item)); 74570700Sjulian} 74670700Sjulian 74770700Sjulianstatic __inline ng_ID_t * 748152451Sglebius_ngi_retaddr(item_p item, char *file, int line) 74970700Sjulian{ 75070700Sjulian _ngi_check(item, file, line); 75170700Sjulian return (&_NGI_RETADDR(item)); 75270700Sjulian} 75370700Sjulian 75471047Sjulianstatic __inline ng_item_fn ** 755152451Sglebius_ngi_fn(item_p item, char *file, int line) 75671047Sjulian{ 75771047Sjulian _ngi_check(item, file, line); 75871047Sjulian return (&_NGI_FN(item)); 75971047Sjulian} 76070700Sjulian 761172806Smavstatic __inline ng_item_fn2 ** 762172806Smav_ngi_fn2(item_p item, char *file, int line) 763172806Smav{ 764172806Smav _ngi_check(item, file, line); 765172806Smav return (&_NGI_FN2(item)); 766172806Smav} 767172806Smav 76871047Sjulianstatic __inline void ** 769152451Sglebius_ngi_arg1(item_p item, char *file, int line) 77071047Sjulian{ 77171047Sjulian _ngi_check(item, file, line); 77271047Sjulian return (&_NGI_ARG1(item)); 77371047Sjulian} 77470700Sjulian 77571047Sjulianstatic __inline int * 776152451Sglebius_ngi_arg2(item_p item, char *file, int line) 77771047Sjulian{ 77871047Sjulian _ngi_check(item, file, line); 77971047Sjulian return (&_NGI_ARG2(item)); 78071047Sjulian} 78170700Sjulian 78271849Sjulianstatic __inline node_p 78371849Sjulian_ngi_node(item_p item, char *file, int line) 78471849Sjulian{ 78571849Sjulian _ngi_check(item, file, line); 78671849Sjulian return (_NGI_NODE(item)); 78771849Sjulian} 78871849Sjulian 78971849Sjulianstatic __inline hook_p 79071849Sjulian_ngi_hook(item_p item, char *file, int line) 79171849Sjulian{ 79271849Sjulian _ngi_check(item, file, line); 79371849Sjulian return (_NGI_HOOK(item)); 79471849Sjulian} 79571849Sjulian 79671047Sjulian#define NGI_M(i) (*_ngi_m(i, _NN_)) 79771047Sjulian#define NGI_MSG(i) (*_ngi_msg(i, _NN_)) 79871047Sjulian#define NGI_RETADDR(i) (*_ngi_retaddr(i, _NN_)) 79971047Sjulian#define NGI_FN(i) (*_ngi_fn(i, _NN_)) 800172806Smav#define NGI_FN2(i) (*_ngi_fn2(i, _NN_)) 80171047Sjulian#define NGI_ARG1(i) (*_ngi_arg1(i, _NN_)) 80271047Sjulian#define NGI_ARG2(i) (*_ngi_arg2(i, _NN_)) 80371849Sjulian#define NGI_HOOK(i) _ngi_hook(i, _NN_) 80471849Sjulian#define NGI_NODE(i) _ngi_node(i, _NN_) 80571849Sjulian#define NGI_SET_HOOK(i,h) \ 80671849Sjulian do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0) 80771849Sjulian#define NGI_CLR_HOOK(i) \ 80871849Sjulian do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0) 80971849Sjulian#define NGI_SET_NODE(i,n) \ 81071849Sjulian do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0) 81171849Sjulian#define NGI_CLR_NODE(i) \ 81271849Sjulian do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0) 81370700Sjulian 81470700Sjulian#define NG_FREE_ITEM(item) \ 81570700Sjulian do { \ 81670784Sjulian _ngi_check(item, _NN_); \ 81770700Sjulian ng_free_item((item)); \ 81870700Sjulian } while (0) 81970700Sjulian 82070700Sjulian#define SAVE_LINE(item) \ 82170700Sjulian do { \ 82270700Sjulian (item)->lastline = __LINE__; \ 82370700Sjulian (item)->lastfile = __FILE__; \ 82470700Sjulian } while (0) 82570700Sjulian 82670784Sjulian#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 82770700Sjulian 82870700Sjulian#define NGI_M(i) _NGI_M(i) 82970700Sjulian#define NGI_MSG(i) _NGI_MSG(i) 83070700Sjulian#define NGI_RETADDR(i) _NGI_RETADDR(i) 83171047Sjulian#define NGI_FN(i) _NGI_FN(i) 832172806Smav#define NGI_FN2(i) _NGI_FN2(i) 83371047Sjulian#define NGI_ARG1(i) _NGI_ARG1(i) 83471047Sjulian#define NGI_ARG2(i) _NGI_ARG2(i) 83571849Sjulian#define NGI_NODE(i) _NGI_NODE(i) 83671849Sjulian#define NGI_HOOK(i) _NGI_HOOK(i) 83771849Sjulian#define NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h) 83871849Sjulian#define NGI_CLR_HOOK(i) _NGI_CLR_HOOK(i) 83971849Sjulian#define NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n) 84071849Sjulian#define NGI_CLR_NODE(i) _NGI_CLR_NODE(i) 84170700Sjulian 84270700Sjulian#define NG_FREE_ITEM(item) ng_free_item((item)) 84370784Sjulian#define SAVE_LINE(item) do {} while (0) 84470700Sjulian 84570784Sjulian#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 84671849Sjulian 84771849Sjulian#define NGI_GET_M(i,m) \ 84871849Sjulian do { \ 84971849Sjulian (m) = NGI_M(i); \ 85071849Sjulian _NGI_M(i) = NULL; \ 85171849Sjulian } while (0) 85271849Sjulian 85371849Sjulian#define NGI_GET_MSG(i,m) \ 85471849Sjulian do { \ 85571849Sjulian (m) = NGI_MSG(i); \ 85671849Sjulian _NGI_MSG(i) = NULL; \ 85771849Sjulian } while (0) 85871849Sjulian 85971849Sjulian#define NGI_GET_NODE(i,n) /* YOU NOW HAVE THE REFERENCE */ \ 86071849Sjulian do { \ 86171849Sjulian (n) = NGI_NODE(i); \ 86271849Sjulian _NGI_NODE(i) = NULL; \ 86371849Sjulian } while (0) 86471849Sjulian 86571849Sjulian#define NGI_GET_HOOK(i,h) \ 86671849Sjulian do { \ 86771849Sjulian (h) = NGI_HOOK(i); \ 86871849Sjulian _NGI_HOOK(i) = NULL; \ 86971849Sjulian } while (0) 87071849Sjulian 871151973Sglebius#define NGI_SET_WRITER(i) ((i)->el_flags &= ~NGQF_QMODE) 872151973Sglebius#define NGI_SET_READER(i) ((i)->el_flags |= NGQF_QREADER) 873151973Sglebius 874151973Sglebius#define NGI_QUEUED_READER(i) ((i)->el_flags & NGQF_QREADER) 875151973Sglebius#define NGI_QUEUED_WRITER(i) (((i)->el_flags & NGQF_QMODE) == NGQF_QWRITER) 87670700Sjulian 87770700Sjulian/********************************************************************** 87870700Sjulian* Data macros. Send, manipulate and free. 87970700Sjulian**********************************************************************/ 88073371Sjulian/* 88173371Sjulian * Assuming the data is already ok, just set the new address and send 88273371Sjulian */ 883154276Sglebius#define NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags) \ 88470700Sjulian do { \ 88573371Sjulian (error) = \ 886154276Sglebius ng_address_hook(NULL, (item), (hook), NG_NOFLAGS); \ 88773371Sjulian if (error == 0) { \ 88873371Sjulian SAVE_LINE(item); \ 889154276Sglebius (error) = ng_snd_item((item), (flags)); \ 89070700Sjulian } \ 89173371Sjulian (item) = NULL; \ 89252419Sjulian } while (0) 893154276Sglebius#define NG_FWD_ITEM_HOOK(error, item, hook) \ 894154276Sglebius NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, NG_NOFLAGS) 89552419Sjulian 89670700Sjulian/* 897131374Sjulian * Forward a data packet. Mbuf pointer is updated to new value. We 898131374Sjulian * presume you dealt with the old one when you update it to the new one 899131374Sjulian * (or it maybe the old one). We got a packet and possibly had to modify 900131374Sjulian * the mbuf. You should probably use NGI_GET_M() if you are going to use 901131374Sjulian * this too. 90270700Sjulian */ 903154276Sglebius#define NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, flags) \ 90459728Sjulian do { \ 90573371Sjulian NGI_M(item) = (m); \ 90673371Sjulian (m) = NULL; \ 907154276Sglebius NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags); \ 90873371Sjulian } while (0) 909154276Sglebius#define NG_FWD_NEW_DATA(error, item, hook, m) \ 910154276Sglebius NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, NG_NOFLAGS) 91173371Sjulian 912131374Sjulian/* Send a previously unpackaged mbuf. XXX: This should be called 913131374Sjulian * NG_SEND_DATA in future, but this name is kept for compatibility 914131374Sjulian * reasons. 915131374Sjulian */ 916154276Sglebius#define NG_SEND_DATA_FLAGS(error, hook, m, flags) \ 91773371Sjulian do { \ 918102190Sarchie item_p _item; \ 919154276Sglebius if ((_item = ng_package_data((m), flags))) { \ 920154276Sglebius NG_FWD_ITEM_HOOK_FLAGS(error, _item, hook, flags);\ 92173371Sjulian } else { \ 92273371Sjulian (error) = ENOMEM; \ 92370700Sjulian } \ 92469922Sjulian (m) = NULL; \ 92569922Sjulian } while (0) 92669922Sjulian 927154276Sglebius#define NG_SEND_DATA_ONLY(error, hook, m) \ 928154276Sglebius NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS) 929154276Sglebius/* NG_SEND_DATA() compat for meta-data times */ 930154276Sglebius#define NG_SEND_DATA(error, hook, m, x) \ 931154276Sglebius NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS) 93259728Sjulian 93370700Sjulian#define NG_FREE_MSG(msg) \ 93470700Sjulian do { \ 93570700Sjulian if ((msg)) { \ 936184205Sdes free((msg), M_NETGRAPH_MSG); \ 93770700Sjulian (msg) = NULL; \ 93870700Sjulian } \ 93970700Sjulian } while (0) 94070700Sjulian 94170700Sjulian#define NG_FREE_M(m) \ 94252419Sjulian do { \ 94352419Sjulian if ((m)) { \ 94452419Sjulian m_freem((m)); \ 94570700Sjulian (m) = NULL; \ 94652419Sjulian } \ 94770700Sjulian } while (0) 94870784Sjulian 94970700Sjulian/***************************************** 95070700Sjulian* Message macros 95170700Sjulian*****************************************/ 95252419Sjulian 95370700Sjulian#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr) \ 95470700Sjulian do { \ 955102190Sarchie item_p _item; \ 956146281Sglebius if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 95770784Sjulian (msg) = NULL; \ 95870784Sjulian (error) = ENOMEM; \ 95970784Sjulian break; \ 96070784Sjulian } \ 961102190Sarchie if (((error) = ng_address_hook((here), (_item), \ 96270784Sjulian (hook), (retaddr))) == 0) { \ 963102190Sarchie SAVE_LINE(_item); \ 964102190Sarchie (error) = ng_snd_item((_item), 0); \ 96570700Sjulian } \ 96670700Sjulian (msg) = NULL; \ 96770700Sjulian } while (0) 96870700Sjulian 96970700Sjulian#define NG_SEND_MSG_PATH(error, here, msg, path, retaddr) \ 97070700Sjulian do { \ 971102190Sarchie item_p _item; \ 972146281Sglebius if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 97370784Sjulian (msg) = NULL; \ 97470784Sjulian (error) = ENOMEM; \ 97570784Sjulian break; \ 97670784Sjulian } \ 977102190Sarchie if (((error) = ng_address_path((here), (_item), \ 97870784Sjulian (path), (retaddr))) == 0) { \ 979102190Sarchie SAVE_LINE(_item); \ 980102190Sarchie (error) = ng_snd_item((_item), 0); \ 98170700Sjulian } \ 98270700Sjulian (msg) = NULL; \ 98370700Sjulian } while (0) 98470700Sjulian 98570700Sjulian#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr) \ 98670700Sjulian do { \ 987102190Sarchie item_p _item; \ 988146281Sglebius if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 98970784Sjulian (msg) = NULL; \ 99070784Sjulian (error) = ENOMEM; \ 99170784Sjulian break; \ 99270784Sjulian } \ 993102190Sarchie if (((error) = ng_address_ID((here), (_item), \ 99470784Sjulian (ID), (retaddr))) == 0) { \ 995102190Sarchie SAVE_LINE(_item); \ 996102190Sarchie (error) = ng_snd_item((_item), 0); \ 99770700Sjulian } \ 99870700Sjulian (msg) = NULL; \ 99970700Sjulian } while (0) 100070700Sjulian 100152419Sjulian/* 100270700Sjulian * Redirect the message to the next hop using the given hook. 100370700Sjulian * ng_retarget_msg() frees the item if there is an error 100470700Sjulian * and returns an error code. It returns 0 on success. 100570700Sjulian */ 100670700Sjulian#define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr) \ 100770700Sjulian do { \ 100870784Sjulian if (((error) = ng_address_hook((here), (item), \ 100970700Sjulian (hook), (retaddr))) == 0) { \ 101070700Sjulian SAVE_LINE(item); \ 101170700Sjulian (error) = ng_snd_item((item), 0); \ 101270700Sjulian } \ 101370700Sjulian (item) = NULL; \ 101470700Sjulian } while (0) 101570700Sjulian 101670700Sjulian/* 101770700Sjulian * Send a queue item back to it's originator with a response message. 101870700Sjulian * Assume original message was removed and freed separatly. 101970700Sjulian */ 102070700Sjulian#define NG_RESPOND_MSG(error, here, item, resp) \ 102170700Sjulian do { \ 102270700Sjulian if (resp) { \ 1023102190Sarchie ng_ID_t _dest = NGI_RETADDR(item); \ 1024102244Sarchie NGI_RETADDR(item) = 0; \ 102570700Sjulian NGI_MSG(item) = resp; \ 1026163460Sglebius if ((error = ng_address_ID((here), (item), \ 1027102244Sarchie _dest, 0)) == 0) { \ 102870700Sjulian SAVE_LINE(item); \ 1029146305Sglebius (error) = ng_snd_item((item), NG_QUEUE);\ 103070700Sjulian } \ 1031163460Sglebius } else \ 103270700Sjulian NG_FREE_ITEM(item); \ 103370700Sjulian (item) = NULL; \ 103470700Sjulian } while (0) 103570700Sjulian 103670700Sjulian 103770784Sjulian/*********************************************************************** 103870784Sjulian ******** Structures Definitions and Macros for defining a node ******* 103970784Sjulian *********************************************************************** 1040152451Sglebius * 104170784Sjulian * Here we define the structures needed to actually define a new node 104270784Sjulian * type. 104370784Sjulian */ 104470784Sjulian 104570700Sjulian/* 104670784Sjulian * Command list -- each node type specifies the command that it knows 104770784Sjulian * how to convert between ASCII and binary using an array of these. 104870784Sjulian * The last element in the array must be a terminator with cookie=0. 104970784Sjulian */ 105070784Sjulian 105170784Sjulianstruct ng_cmdlist { 105270784Sjulian u_int32_t cookie; /* command typecookie */ 105370784Sjulian int cmd; /* command number */ 105470784Sjulian const char *name; /* command name */ 105570784Sjulian const struct ng_parse_type *mesgType; /* args if !NGF_RESP */ 105670784Sjulian const struct ng_parse_type *respType; /* args if NGF_RESP */ 105770784Sjulian}; 105870784Sjulian 105970784Sjulian/* 106070784Sjulian * Structure of a node type 106170784Sjulian * If data is sent to the "rcvdata()" entrypoint then the system 106270784Sjulian * may decide to defer it until later by queing it with the normal netgraph 106370784Sjulian * input queuing system. This is decidde by the HK_QUEUE flag being set in 106470784Sjulian * the flags word of the peer (receiving) hook. The dequeuing mechanism will 106570784Sjulian * ensure it is not requeued again. 106670784Sjulian * Note the input queueing system is to allow modules 106770784Sjulian * to 'release the stack' or to pass data across spl layers. 106870784Sjulian * The data will be redelivered as soon as the NETISR code runs 106970784Sjulian * which may be almost immediatly. A node may also do it's own queueing 107070784Sjulian * for other reasons (e.g. device output queuing). 107170784Sjulian */ 107270784Sjulianstruct ng_type { 107370784Sjulian 107470784Sjulian u_int32_t version; /* must equal NG_API_VERSION */ 107570784Sjulian const char *name; /* Unique type name */ 107670784Sjulian modeventhand_t mod_event; /* Module event handler (optional) */ 107770784Sjulian ng_constructor_t *constructor; /* Node constructor */ 107870784Sjulian ng_rcvmsg_t *rcvmsg; /* control messages come here */ 1079129836Sjulian ng_close_t *close; /* warn about forthcoming shutdown */ 108070784Sjulian ng_shutdown_t *shutdown; /* reset, and free resources */ 108170784Sjulian ng_newhook_t *newhook; /* first notification of new hook */ 108270784Sjulian ng_findhook_t *findhook; /* only if you have lots of hooks */ 108370784Sjulian ng_connect_t *connect; /* final notification of new hook */ 108470784Sjulian ng_rcvdata_t *rcvdata; /* data comes here */ 108570784Sjulian ng_disconnect_t *disconnect; /* notify on disconnect */ 108670784Sjulian 108770784Sjulian const struct ng_cmdlist *cmdlist; /* commands we can convert */ 108870784Sjulian 108970784Sjulian /* R/W data private to the base netgraph code DON'T TOUCH! */ 109070784Sjulian LIST_ENTRY(ng_type) types; /* linked list of all types */ 109170784Sjulian int refs; /* number of instances */ 109270784Sjulian}; 109370784Sjulian 109470784Sjulian/* 109552419Sjulian * Use the NETGRAPH_INIT() macro to link a node type into the 109652419Sjulian * netgraph system. This works for types compiled into the kernel 109752419Sjulian * as well as KLD modules. The first argument should be the type 109852419Sjulian * name (eg, echo) and the second a pointer to the type struct. 109952419Sjulian * 110052419Sjulian * If a different link time is desired, e.g., a device driver that 110152419Sjulian * needs to install its netgraph type before probing, use the 1102148646Sru * NETGRAPH_INIT_ORDERED() macro instead. Device drivers probably 1103148646Sru * want to use SI_SUB_DRIVERS/SI_ORDER_FIRST. 110452419Sjulian */ 110552419Sjulian 110652419Sjulian#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \ 110752419Sjulianstatic moduledata_t ng_##typename##_mod = { \ 110852419Sjulian "ng_" #typename, \ 110952419Sjulian ng_mod_event, \ 111052419Sjulian (typestructp) \ 111152419Sjulian}; \ 111259756SpeterDECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \ 111372053SjulianMODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \ 111472053Sjulian NG_ABI_VERSION, \ 111572053Sjulian NG_ABI_VERSION) 111652419Sjulian 111752419Sjulian#define NETGRAPH_INIT(tn, tp) \ 1118195837Srwatson NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_MIDDLE) 111952419Sjulian 112052419Sjulian/* Special malloc() type for netgraph structs and ctrl messages */ 1121152451Sglebius/* Only these two types should be visible to nodes */ 112252419SjulianMALLOC_DECLARE(M_NETGRAPH); 112370700SjulianMALLOC_DECLARE(M_NETGRAPH_MSG); 112452419Sjulian 112572946Sjulian/* declare the base of the netgraph sysclt hierarchy */ 112672946Sjulian/* but only if this file cares about sysctls */ 112772946Sjulian#ifdef SYSCTL_DECL 112872946SjulianSYSCTL_DECL(_net_graph); 112972946Sjulian#endif 113070700Sjulian 113170784Sjulian/* 113270784Sjulian * Methods that the nodes can use. 1133152451Sglebius * Many of these methods should usually NOT be used directly but via 113470784Sjulian * Macros above. 113570784Sjulian */ 113670700Sjulianint ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr); 113770700Sjulianint ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr); 1138227130Sfjoeint ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr); 1139129836Sjulianint ng_bypass(hook_p hook1, hook_p hook2); 114054096Sarchiehook_p ng_findhook(node_p node, const char *name); 1141132705Sglebiusstruct ng_type *ng_findtype(const char *type); 114252419Sjulianint ng_make_node_common(struct ng_type *typep, node_p *nodep); 114352419Sjulianint ng_name_node(node_p node, const char *name); 1144191510Szecnode_p ng_name2noderef(node_p node, const char *name); 114552419Sjulianint ng_newtype(struct ng_type *tp); 114652722Sjulianng_ID_t ng_node2ID(node_p node); 1147146281Sglebiusitem_p ng_package_data(struct mbuf *m, int flags); 1148146281Sglebiusitem_p ng_package_msg(struct ng_mesg *msg, int flags); 114970700Sjulianitem_p ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg); 115070700Sjulianvoid ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr); 115170935Sjulianint ng_rmhook_self(hook_p hook); /* if a node wants to kill a hook */ 115270935Sjulianint ng_rmnode_self(node_p here); /* if a node wants to suicide */ 115380222Sjulianint ng_rmtype(struct ng_type *tp); 115470700Sjulianint ng_snd_item(item_p item, int queue); 1155173605Sglebiusint ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void *arg1, 1156173605Sglebius int arg2); 1157173605Sglebiusint ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void *arg1, 1158173605Sglebius int arg2, int flags); 1159173605Sglebiusint ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn, 1160146281Sglebius void *arg1, int arg2, int flags); 1161138268Sglebiusint ng_uncallout(struct callout *c, node_p node); 1162138268Sglebiusint ng_callout(struct callout *c, node_p node, hook_p hook, int ticks, 116391711Sjulian ng_item_fn *fn, void * arg1, int arg2); 1164171637Srwatson#define ng_callout_init(c) callout_init(c, CALLOUT_MPSAFE) 116552419Sjulian 1166146281Sglebius/* Flags for netgraph functions. */ 1167146281Sglebius#define NG_NOFLAGS 0x00000000 /* no special options */ 1168146281Sglebius#define NG_QUEUE 0x00000001 /* enqueue item, don't dispatch */ 1169146281Sglebius#define NG_WAITOK 0x00000002 /* use M_WAITOK, etc. */ 1170173605Sglebius/* XXXGL: NG_PROGRESS unused since ng_base.c rev. 1.136. Should be deleted? */ 1171147774Sglebius#define NG_PROGRESS 0x00000004 /* return EINPROGRESS if queued */ 1172173605Sglebius#define NG_REUSE_ITEM 0x00000008 /* supplied item should be reused */ 1173146281Sglebius 117470784Sjulian/* 1175131108Sjulian * prototypes the user should DEFINITELY not use directly 117670784Sjulian */ 117770784Sjulianvoid ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */ 117870784Sjulianint ng_mod_event(module_t mod, int what, void *arg); 117970784Sjulian 1180131108Sjulian/* 1181131108Sjulian * Tag definitions and constants 1182131108Sjulian */ 1183131108Sjulian 1184131108Sjulian#define NG_TAG_PRIO 1 1185131108Sjulian 1186131108Sjulianstruct ng_tag_prio { 1187131108Sjulian struct m_tag tag; 1188131108Sjulian char priority; 1189131108Sjulian char discardability; 1190131108Sjulian}; 1191131108Sjulian 1192131108Sjulian#define NG_PRIO_CUTOFF 32 1193131108Sjulian#define NG_PRIO_LINKSTATE 64 1194131108Sjulian 1195131374Sjulian/* Macros and declarations to keep compatibility with metadata, which 1196131374Sjulian * is obsoleted now. To be deleted. 1197131374Sjulian */ 1198131374Sjuliantypedef void *meta_p; 1199131374Sjulian#define _NGI_META(i) NULL 1200131374Sjulian#define NGI_META(i) NULL 1201131374Sjulian#define NG_FREE_META(meta) 1202131374Sjulian#define NGI_GET_META(i,m) 1203131374Sjulian#define ng_copy_meta(meta) NULL 1204131374Sjulian 1205194012Szec/* 1206194012Szec * Mark the current thread when called from the outbound path of the 1207194012Szec * network stack, in order to enforce queuing on ng nodes calling into 1208194012Szec * the inbound network stack path. 1209194012Szec */ 1210194012Szec#define NG_OUTBOUND_THREAD_REF() \ 1211194012Szec curthread->td_ng_outbound++ 1212194012Szec#define NG_OUTBOUND_THREAD_UNREF() \ 1213194012Szec do { \ 1214194012Szec curthread->td_ng_outbound--; \ 1215194012Szec KASSERT(curthread->td_ng_outbound >= 0, \ 1216194012Szec ("%s: negative td_ng_outbound", __func__)); \ 1217194012Szec } while (0) 1218194012Szec 121952419Sjulian#endif /* _NETGRAPH_NETGRAPH_H_ */ 1220