netgraph.h revision 314667
1339631Sphilip/* 2339631Sphilip * netgraph.h 3192886Sedwin */ 4192886Sedwin 564499Swollman/*- 6273719Sedwin * Copyright (c) 1996-1999 Whistle Communications, Inc. 72742Swollman * All rights reserved. 8273719Sedwin * 9273719Sedwin * Subject to the following obligations and disclaimer of warranty, use and 102742Swollman * redistribution of this software, in source or object code forms, with or 11339631Sphilip * without modifications are expressly permitted by Whistle Communications; 122742Swollman * provided, however, that: 13274563Sedwin * 1. Any and all reproductions of the source or object code must include the 14158421Swollman * copyright notice above and the following disclaimer of warranties; and 15158421Swollman * 2. No rights are granted, in any manner or form, to use Whistle 16274563Sedwin * Communications, Inc. trademarks, including the mark "WHISTLE 172742Swollman * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18316350Sbapt * such appears in the above copyright notice or in the software. 19316350Sbapt * 2020094Swollman * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 2120094Swollman * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22274563Sedwin * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23274563Sedwin * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2420094Swollman * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 252742Swollman * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 262742Swollman * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 272742Swollman * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 282742Swollman * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29248307Sedwin * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30273719Sedwin * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31325160Sphilip * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32248307Sedwin * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33273719Sedwin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34273719Sedwin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35273719Sedwin * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36273719Sedwin * OF SUCH DAMAGE. 372742Swollman * 3858787Sru * Author: Julian Elischer <julian@freebsd.org> 392742Swollman * 40339631Sphilip * $FreeBSD: stable/10/sys/netgraph/netgraph.h 314667 2017-03-04 13:03:31Z avg $ 41339631Sphilip * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $ 42114173Swollman */ 43114173Swollman 44114173Swollman#ifndef _NETGRAPH_NETGRAPH_H_ 45114173Swollman#define _NETGRAPH_NETGRAPH_H_ 46114173Swollman 47257697Sedwin#ifndef _KERNEL 48257697Sedwin#error "This file should not be included in user level programs" 49114173Swollman#endif 50339631Sphilip 51316350Sbapt#include <sys/queue.h> 52257697Sedwin#include <sys/lock.h> 53149590Swollman#include <sys/malloc.h> 54286751Sedwin#include <sys/module.h> 55270817Spluknet#include <sys/mutex.h> 56339631Sphilip#include <sys/refcount.h> 57316350Sbapt 58328476Sphilip#ifdef HAVE_KERNEL_OPTION_HEADERS 59316350Sbapt#include "opt_netgraph.h" 60316350Sbapt#include "opt_kdb.h" 612742Swollman#endif 62270817Spluknet 632742Swollman/* debugging options */ 642742Swollman#define NG_SEPARATE_MALLOC /* make modules use their own malloc types */ 652742Swollman 662742Swollman/* 672742Swollman * This defines the in-kernel binary interface version. 68316350Sbapt * It is possible to change this but leave the external message 692742Swollman * API the same. Each type also has it's own cookies for versioning as well. 702742Swollman * Change it for NETGRAPH_DEBUG version so we cannot mix debug and non debug 712742Swollman * modules. 72270817Spluknet */ 732742Swollman#define _NG_ABI_VERSION 12 7420094Swollman#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 75158421Swollman#define NG_ABI_VERSION (_NG_ABI_VERSION + 0x10000) 7620094Swollman#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 77331663Sphilip#define NG_ABI_VERSION _NG_ABI_VERSION 7820094Swollman#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 7920094Swollman 80331663Sphilip 8120094Swollman/* 82307362Sbapt * Forward references for the basic structures so we can 83331663Sphilip * define the typedefs and use them in the structures themselves. 84325160Sphilip */ 852742Swollmanstruct ng_hook ; 862742Swollmanstruct ng_node ; 872742Swollmanstruct ng_item ; 882742Swollmantypedef struct ng_item *item_p; 89316350Sbapttypedef struct ng_node *node_p; 90316350Sbapttypedef struct ng_hook *hook_p; 912742Swollman 922742Swollman/* node method definitions */ 93158421Swollmantypedef int ng_constructor_t(node_p node); 94158421Swollmantypedef int ng_close_t(node_p node); 95158421Swollmantypedef int ng_shutdown_t(node_p node); 96158421Swollmantypedef int ng_newhook_t(node_p node, hook_p hook, const char *name); 97158421Swollmantypedef hook_p ng_findhook_t(node_p node, const char *name); 98153670Swollmantypedef int ng_connect_t(hook_p hook); 9943014Swollmantypedef int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook); 10043014Swollmantypedef int ng_rcvdata_t(hook_p hook, item_p item); 10143014Swollmantypedef int ng_disconnect_t(hook_p hook); 102233445Sedwintypedef int ng_rcvitem (node_p node, hook_p hook, item_p item); 103233445Sedwin 104233445Sedwin/*********************************************************************** 105233445Sedwin ***************** Hook Structure and Methods ************************** 106233445Sedwin *********************************************************************** 107233445Sedwin * 108233445Sedwin * Structure of a hook 109233445Sedwin */ 110240457Sedwinstruct ng_hook { 111233445Sedwin char hk_name[NG_HOOKSIZ]; /* what this node knows this link as */ 112233445Sedwin void *hk_private; /* node dependant ID for this hook */ 113233445Sedwin int hk_flags; /* info about this hook/link */ 114233445Sedwin int hk_type; /* tbd: hook data link type */ 115233445Sedwin struct ng_hook *hk_peer; /* the other end of this link */ 116233445Sedwin struct ng_node *hk_node; /* The node this hook is attached to */ 117325160Sphilip LIST_ENTRY(ng_hook) hk_hooks; /* linked list of all hooks on node */ 118331663Sphilip ng_rcvmsg_t *hk_rcvmsg; /* control messages come here */ 119325160Sphilip ng_rcvdata_t *hk_rcvdata; /* data comes here */ 1202742Swollman int hk_refs; /* dont actually free this till 0 */ 1212742Swollman#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 122307362Sbapt#define HK_MAGIC 0x78573011 123307362Sbapt int hk_magic; 124307362Sbapt char *lastfile; 125307362Sbapt int lastline; 126325160Sphilip SLIST_ENTRY(ng_hook) hk_all; /* all existing items */ 127325160Sphilip#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 1282742Swollman}; 1292742Swollman/* Flags for a hook */ 130307362Sbapt#define HK_INVALID 0x0001 /* don't trust it! */ 131153670Swollman#define HK_QUEUE 0x0002 /* queue for later delivery */ 132153670Swollman#define HK_FORCE_WRITER 0x0004 /* Incoming data queued as a writer */ 133290698Sedwin#define HK_DEAD 0x0008 /* This is the dead hook.. don't free */ 134290698Sedwin#define HK_HI_STACK 0x0010 /* Hook has hi stack usage */ 135307362Sbapt#define HK_TO_INBOUND 0x0020 /* Hook on ntw. stack inbound path. */ 136307362Sbapt 137307362Sbapt/* 138307362Sbapt * Public Methods for hook 139325160Sphilip * If you can't do it with these you probably shouldn;t be doing it. 140307362Sbapt */ 141307362Sbaptvoid ng_unref_hook(hook_p hook); /* don't move this */ 142307362Sbapt#define _NG_HOOK_REF(hook) refcount_acquire(&(hook)->hk_refs) 14343014Swollman#define _NG_HOOK_NAME(hook) ((hook)->hk_name) 144331663Sphilip#define _NG_HOOK_UNREF(hook) ng_unref_hook(hook) 145307362Sbapt#define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0) 1462742Swollman#define _NG_HOOK_SET_RCVMSG(hook, val) do {(hook)->hk_rcvmsg = val;} while (0) 1472742Swollman#define _NG_HOOK_SET_RCVDATA(hook, val) do {(hook)->hk_rcvdata = val;} while (0) 148307362Sbapt#define _NG_HOOK_PRIVATE(hook) ((hook)->hk_private) 149307362Sbapt#define _NG_HOOK_NOT_VALID(hook) ((hook)->hk_flags & HK_INVALID) 150307362Sbapt#define _NG_HOOK_IS_VALID(hook) (!((hook)->hk_flags & HK_INVALID)) 151307362Sbapt#define _NG_HOOK_NODE(hook) ((hook)->hk_node) /* only rvalue! */ 152307362Sbapt#define _NG_HOOK_PEER(hook) ((hook)->hk_peer) /* only rvalue! */ 153307362Sbapt#define _NG_HOOK_FORCE_WRITER(hook) \ 1542742Swollman do { hook->hk_flags |= HK_FORCE_WRITER; } while (0) 1552742Swollman#define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0) 156279707Sedwin#define _NG_HOOK_SET_TO_INBOUND(hook) \ 1572742Swollman do { hook->hk_flags |= HK_TO_INBOUND; } while (0) 1582742Swollman#define _NG_HOOK_HI_STACK(hook) do { hook->hk_flags |= HK_HI_STACK; } while (0) 159193785Sedwin 160193785Sedwin/* Some shortcuts */ 161193785Sedwin#define NG_PEER_NODE(hook) NG_HOOK_NODE(NG_HOOK_PEER(hook)) 162193785Sedwin#define NG_PEER_HOOK_NAME(hook) NG_HOOK_NAME(NG_HOOK_PEER(hook)) 163193785Sedwin#define NG_PEER_NODE_NAME(hook) NG_NODE_NAME(NG_PEER_NODE(hook)) 164193785Sedwin 165193785Sedwin#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 166193785Sedwin#define _NN_ __FILE__,__LINE__ 167193785Sedwinvoid dumphook (hook_p hook, char *file, int line); 168193785Sedwinstatic __inline void _chkhook(hook_p hook, char *file, int line); 169193785Sedwinstatic __inline void _ng_hook_ref(hook_p hook, char * file, int line); 170193785Sedwinstatic __inline char * _ng_hook_name(hook_p hook, char * file, int line); 171193785Sedwinstatic __inline void _ng_hook_unref(hook_p hook, char * file, int line); 172193785Sedwinstatic __inline void _ng_hook_set_private(hook_p hook, 173193785Sedwin void * val, char * file, int line); 174193785Sedwinstatic __inline void _ng_hook_set_rcvmsg(hook_p hook, 175193785Sedwin ng_rcvmsg_t *val, char * file, int line); 176193785Sedwinstatic __inline void _ng_hook_set_rcvdata(hook_p hook, 177193785Sedwin ng_rcvdata_t *val, char * file, int line); 178193785Sedwinstatic __inline void * _ng_hook_private(hook_p hook, char * file, int line); 179193785Sedwinstatic __inline int _ng_hook_not_valid(hook_p hook, char * file, int line); 180325160Sphilipstatic __inline int _ng_hook_is_valid(hook_p hook, char * file, int line); 181193785Sedwinstatic __inline node_p _ng_hook_node(hook_p hook, char * file, int line); 182193785Sedwinstatic __inline hook_p _ng_hook_peer(hook_p hook, char * file, int line); 183193785Sedwinstatic __inline void _ng_hook_force_writer(hook_p hook, char * file, 184325160Sphilip int line); 185193785Sedwinstatic __inline void _ng_hook_force_queue(hook_p hook, char * file, 186194485Sedwin int line); 187240457Sedwinstatic __inline void _ng_hook_set_to_inbound(hook_p hook, char * file, 188240457Sedwin int line); 189240457Sedwin 190194485Sedwinstatic __inline void 191194485Sedwin_chkhook(hook_p hook, char *file, int line) 192193785Sedwin{ 193198270Sedwin if (hook->hk_magic != HK_MAGIC) { 194240457Sedwin printf("Accessing freed "); 195240457Sedwin dumphook(hook, file, line); 196198270Sedwin } 197198270Sedwin hook->lastline = line; 198198270Sedwin hook->lastfile = file; 199198270Sedwin} 200198270Sedwin 201196581Sedwinstatic __inline void 202198270Sedwin_ng_hook_ref(hook_p hook, char * file, int line) 203198270Sedwin{ 204240457Sedwin _chkhook(hook, file, line); 205240457Sedwin _NG_HOOK_REF(hook); 206198270Sedwin} 207198270Sedwin 208198270Sedwinstatic __inline char * 209198270Sedwin_ng_hook_name(hook_p hook, char * file, int line) 210198270Sedwin{ 211201189Sedwin _chkhook(hook, file, line); 212201189Sedwin return (_NG_HOOK_NAME(hook)); 213201189Sedwin} 214201189Sedwin 215201189Sedwinstatic __inline void 216201189Sedwin_ng_hook_unref(hook_p hook, char * file, int line) 217201189Sedwin{ 218201189Sedwin _chkhook(hook, file, line); 219201189Sedwin _NG_HOOK_UNREF(hook); 220201189Sedwin} 221201189Sedwin 222201189Sedwinstatic __inline void 223201189Sedwin_ng_hook_set_private(hook_p hook, void *val, char * file, int line) 224206219Sedwin{ 225206219Sedwin _chkhook(hook, file, line); 226240457Sedwin _NG_HOOK_SET_PRIVATE(hook, val); 227206219Sedwin} 228206219Sedwin 229204887Sedwinstatic __inline void 230201189Sedwin_ng_hook_set_rcvmsg(hook_p hook, ng_rcvmsg_t *val, char * file, int line) 231331663Sphilip{ 232273719Sedwin _chkhook(hook, file, line); 233201189Sedwin _NG_HOOK_SET_RCVMSG(hook, val); 2342742Swollman} 23575267Swollman 23619878Swollmanstatic __inline void 237316350Sbapt_ng_hook_set_rcvdata(hook_p hook, ng_rcvdata_t *val, char * file, int line) 238316350Sbapt{ 239316350Sbapt _chkhook(hook, file, line); 240316350Sbapt _NG_HOOK_SET_RCVDATA(hook, val); 241316350Sbapt} 2422742Swollman 2432742Swollmanstatic __inline void * 2442742Swollman_ng_hook_private(hook_p hook, char * file, int line) 24567578Swollman{ 246316350Sbapt _chkhook(hook, file, line); 247316350Sbapt return (_NG_HOOK_PRIVATE(hook)); 2482742Swollman} 2492742Swollman 25086222Swollmanstatic __inline int 25186222Swollman_ng_hook_not_valid(hook_p hook, char * file, int line) 252149514Swollman{ 253149514Swollman _chkhook(hook, file, line); 254149514Swollman return (_NG_HOOK_NOT_VALID(hook)); 2552742Swollman} 256149514Swollman 257316350Sbaptstatic __inline int 258316350Sbapt_ng_hook_is_valid(hook_p hook, char * file, int line) 2592742Swollman{ 2602742Swollman _chkhook(hook, file, line); 2612742Swollman return (_NG_HOOK_IS_VALID(hook)); 262273719Sedwin} 263316350Sbapt 264316350Sbaptstatic __inline node_p 2652742Swollman_ng_hook_node(hook_p hook, char * file, int line) 26614343Swollman{ 267248307Sedwin _chkhook(hook, file, line); 268248307Sedwin return (_NG_HOOK_NODE(hook)); 269248307Sedwin} 270325160Sphilip 271325160Sphilipstatic __inline hook_p 272325160Sphilip_ng_hook_peer(hook_p hook, char * file, int line) 273325160Sphilip{ 274325160Sphilip _chkhook(hook, file, line); 275325160Sphilip return (_NG_HOOK_PEER(hook)); 2762742Swollman} 277325160Sphilip 278325160Sphilipstatic __inline void 279316350Sbapt_ng_hook_force_writer(hook_p hook, char * file, int line) 280316350Sbapt{ 281316350Sbapt _chkhook(hook, file, line); 2822742Swollman _NG_HOOK_FORCE_WRITER(hook); 2832742Swollman} 284273719Sedwin 2852742Swollmanstatic __inline void 286273719Sedwin_ng_hook_force_queue(hook_p hook, char * file, int line) 28743014Swollman{ 2882742Swollman _chkhook(hook, file, line); 289339631Sphilip _NG_HOOK_FORCE_QUEUE(hook); 290339631Sphilip} 291339631Sphilip 292339631Sphilipstatic __inline void 293339631Sphilip_ng_hook_set_to_inbound(hook_p hook, char * file, int line) 294339631Sphilip{ 295339631Sphilip _chkhook(hook, file, line); 296339631Sphilip _NG_HOOK_SET_TO_INBOUND(hook); 297339631Sphilip} 298339631Sphilip 299339631Sphilipstatic __inline void 300339631Sphilip_ng_hook_hi_stack(hook_p hook, char * file, int line) 301339631Sphilip{ 302339631Sphilip _chkhook(hook, file, line); 303339631Sphilip _NG_HOOK_HI_STACK(hook); 304339631Sphilip} 305339631Sphilip 306339631Sphilip 307339631Sphilip#define NG_HOOK_REF(hook) _ng_hook_ref(hook, _NN_) 308339631Sphilip#define NG_HOOK_NAME(hook) _ng_hook_name(hook, _NN_) 309339631Sphilip#define NG_HOOK_UNREF(hook) _ng_hook_unref(hook, _NN_) 310339631Sphilip#define NG_HOOK_SET_PRIVATE(hook, val) _ng_hook_set_private(hook, val, _NN_) 311339631Sphilip#define NG_HOOK_SET_RCVMSG(hook, val) _ng_hook_set_rcvmsg(hook, val, _NN_) 3122742Swollman#define NG_HOOK_SET_RCVDATA(hook, val) _ng_hook_set_rcvdata(hook, val, _NN_) 3132742Swollman#define NG_HOOK_PRIVATE(hook) _ng_hook_private(hook, _NN_) 3142742Swollman#define NG_HOOK_NOT_VALID(hook) _ng_hook_not_valid(hook, _NN_) 31519878Swollman#define NG_HOOK_IS_VALID(hook) _ng_hook_is_valid(hook, _NN_) 31619878Swollman#define NG_HOOK_NODE(hook) _ng_hook_node(hook, _NN_) 3172742Swollman#define NG_HOOK_PEER(hook) _ng_hook_peer(hook, _NN_) 318270817Spluknet#define NG_HOOK_FORCE_WRITER(hook) _ng_hook_force_writer(hook, _NN_) 319270817Spluknet#define NG_HOOK_FORCE_QUEUE(hook) _ng_hook_force_queue(hook, _NN_) 32093799Swollman#define NG_HOOK_SET_TO_INBOUND(hook) _ng_hook_set_to_inbound(hook, _NN_) 3212742Swollman#define NG_HOOK_HI_STACK(hook) _ng_hook_hi_stack(hook, _NN_) 3222742Swollman 323270817Spluknet#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 3242742Swollman 3252742Swollman#define NG_HOOK_REF(hook) _NG_HOOK_REF(hook) 3262742Swollman#define NG_HOOK_NAME(hook) _NG_HOOK_NAME(hook) 3272742Swollman#define NG_HOOK_UNREF(hook) _NG_HOOK_UNREF(hook) 3282742Swollman#define NG_HOOK_SET_PRIVATE(hook, val) _NG_HOOK_SET_PRIVATE(hook, val) 32919878Swollman#define NG_HOOK_SET_RCVMSG(hook, val) _NG_HOOK_SET_RCVMSG(hook, val) 3302742Swollman#define NG_HOOK_SET_RCVDATA(hook, val) _NG_HOOK_SET_RCVDATA(hook, val) 3312742Swollman#define NG_HOOK_PRIVATE(hook) _NG_HOOK_PRIVATE(hook) 3322742Swollman#define NG_HOOK_NOT_VALID(hook) _NG_HOOK_NOT_VALID(hook) 333270817Spluknet#define NG_HOOK_IS_VALID(hook) _NG_HOOK_IS_VALID(hook) 334270817Spluknet#define NG_HOOK_NODE(hook) _NG_HOOK_NODE(hook) 335270817Spluknet#define NG_HOOK_PEER(hook) _NG_HOOK_PEER(hook) 336270817Spluknet#define NG_HOOK_FORCE_WRITER(hook) _NG_HOOK_FORCE_WRITER(hook) 3372742Swollman#define NG_HOOK_FORCE_QUEUE(hook) _NG_HOOK_FORCE_QUEUE(hook) 338339631Sphilip#define NG_HOOK_SET_TO_INBOUND(hook) _NG_HOOK_SET_TO_INBOUND(hook) 339339631Sphilip#define NG_HOOK_HI_STACK(hook) _NG_HOOK_HI_STACK(hook) 340339631Sphilip 341339631Sphilip#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 342339631Sphilip 343339631Sphilip/*********************************************************************** 344339631Sphilip ***************** Node Structure and Methods ************************** 345339631Sphilip *********************************************************************** 346339631Sphilip * Structure of a node 347339631Sphilip * including the eembedded queue structure. 348339631Sphilip * 349339631Sphilip * The structure for queueing Netgraph request items 350339631Sphilip * embedded in the node structure 351339631Sphilip */ 352339631Sphilipstruct ng_queue { 353339631Sphilip u_int q_flags; /* Current r/w/q lock flags */ 354339631Sphilip u_int q_flags2; /* Other queue flags */ 355339631Sphilip struct mtx q_mtx; 356339631Sphilip STAILQ_ENTRY(ng_node) q_work; /* nodes with work to do */ 357339631Sphilip STAILQ_HEAD(, ng_item) queue; /* actually items queue */ 358339631Sphilip}; 359339631Sphilip 360339631Sphilipstruct ng_node { 3612742Swollman char nd_name[NG_NODESIZ]; /* optional globally unique name */ 362339631Sphilip struct ng_type *nd_type; /* the installed 'type' */ 363339631Sphilip int nd_flags; /* see below for bit definitions */ 364339631Sphilip int nd_numhooks; /* number of hooks */ 365163302Sru void *nd_private; /* node type dependant node ID */ 36693799Swollman ng_ID_t nd_ID; /* Unique per node */ 36793799Swollman LIST_HEAD(hooks, ng_hook) nd_hooks; /* linked list of node hooks */ 36893799Swollman LIST_ENTRY(ng_node) nd_nodes; /* name hash collision list */ 369163302Sru LIST_ENTRY(ng_node) nd_idnodes; /* ID hash collision list */ 370169811Swollman struct ng_queue nd_input_queue; /* input queue for locking */ 371270817Spluknet int nd_refs; /* # of references to this node */ 372163302Sru struct vnet *nd_vnet; /* network stack instance */ 373325160Sphilip#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 374163302Sru#define ND_MAGIC 0x59264837 375163302Sru int nd_magic; 376163302Sru char *lastfile; 377163302Sru int lastline; 378163302Sru SLIST_ENTRY(ng_node) nd_all; /* all existing nodes */ 379163302Sru#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 380163302Sru}; 381163302Sru 382316350Sbapt/* Flags for a node */ 383270817Spluknet#define NGF_INVALID 0x00000001 /* free when refs go to 0 */ 384181421Sedwin#define NG_INVALID NGF_INVALID /* compat for old code */ 385270817Spluknet#define NGF_FORCE_WRITER 0x00000004 /* Never multithread this node */ 386339631Sphilip#define NG_FORCE_WRITER NGF_FORCE_WRITER /* compat for old code */ 387270817Spluknet#define NGF_CLOSING 0x00000008 /* ng_rmnode() at work */ 388270817Spluknet#define NG_CLOSING NGF_CLOSING /* compat for old code */ 389339631Sphilip#define NGF_REALLY_DIE 0x00000010 /* "persistent" node is unloading */ 390339631Sphilip#define NG_REALLY_DIE NGF_REALLY_DIE /* compat for old code */ 391270817Spluknet#define NGF_HI_STACK 0x00000020 /* node has hi stack usage */ 392270817Spluknet#define NGF_TYPE1 0x10000000 /* reserved for type specific storage */ 393270817Spluknet#define NGF_TYPE2 0x20000000 /* reserved for type specific storage */ 394270817Spluknet#define NGF_TYPE3 0x40000000 /* reserved for type specific storage */ 395270817Spluknet#define NGF_TYPE4 0x80000000 /* reserved for type specific storage */ 396270817Spluknet 397270817Spluknet/* 398270817Spluknet * Public methods for nodes. 399181421Sedwin * If you can't do it with these you probably shouldn't be doing it. 400270817Spluknet */ 401270817Spluknetvoid ng_unref_node(node_p node); /* don't move this */ 402270817Spluknet#define _NG_NODE_NAME(node) ((node)->nd_name + 0) 403270817Spluknet#define _NG_NODE_HAS_NAME(node) ((node)->nd_name[0] + 0) 404270817Spluknet#define _NG_NODE_ID(node) ((node)->nd_ID + 0) 405270817Spluknet#define _NG_NODE_REF(node) refcount_acquire(&(node)->nd_refs) 406270817Spluknet#define _NG_NODE_UNREF(node) ng_unref_node(node) 407270817Spluknet#define _NG_NODE_SET_PRIVATE(node, val) do {(node)->nd_private = val;} while (0) 408270817Spluknet#define _NG_NODE_PRIVATE(node) ((node)->nd_private) 409273719Sedwin#define _NG_NODE_IS_VALID(node) (!((node)->nd_flags & NGF_INVALID)) 410273719Sedwin#define _NG_NODE_NOT_VALID(node) ((node)->nd_flags & NGF_INVALID) 411270817Spluknet#define _NG_NODE_NUMHOOKS(node) ((node)->nd_numhooks + 0) /* rvalue */ 412270817Spluknet#define _NG_NODE_FORCE_WRITER(node) \ 413270817Spluknet do{ node->nd_flags |= NGF_FORCE_WRITER; }while (0) 414270817Spluknet#define _NG_NODE_HI_STACK(node) \ 415270817Spluknet do{ node->nd_flags |= NGF_HI_STACK; }while (0) 416270817Spluknet#define _NG_NODE_REALLY_DIE(node) \ 417270817Spluknet do{ node->nd_flags |= (NGF_REALLY_DIE|NGF_INVALID); }while (0) 418270817Spluknet#define _NG_NODE_REVIVE(node) \ 419270817Spluknet do { node->nd_flags &= ~NGF_INVALID; } while (0) 420270817Spluknet/* 421270817Spluknet * The hook iterator. 422270817Spluknet * This macro will call a function of type ng_fn_eachhook for each 423270817Spluknet * hook attached to the node. If the function returns 0, then the 424270817Spluknet * iterator will stop and return a pointer to the hook that returned 0. 425270817Spluknet */ 426270817Spluknettypedef int ng_fn_eachhook(hook_p hook, void* arg); 427270817Spluknet#define _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 428270817Spluknet do { \ 429270817Spluknet hook_p _hook; \ 430270817Spluknet (rethook) = NULL; \ 431307362Sbapt LIST_FOREACH(_hook, &((node)->nd_hooks), hk_hooks) { \ 432270817Spluknet if ((fn)(_hook, arg) == 0) { \ 433270817Spluknet (rethook) = _hook; \ 434273719Sedwin break; \ 435270817Spluknet } \ 436270817Spluknet } \ 437270817Spluknet } while (0) 438270817Spluknet 439270817Spluknet#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 440307362Sbaptvoid dumpnode(node_p node, char *file, int line); 441316350Sbaptstatic __inline void _chknode(node_p node, char *file, int line); 442163302Srustatic __inline char * _ng_node_name(node_p node, char *file, int line); 443270817Spluknetstatic __inline int _ng_node_has_name(node_p node, char *file, int line); 444307362Sbaptstatic __inline ng_ID_t _ng_node_id(node_p node, char *file, int line); 445316350Sbaptstatic __inline void _ng_node_ref(node_p node, char *file, int line); 446163302Srustatic __inline void _ng_node_unref(node_p node, char *file, int line); 447270817Spluknetstatic __inline void _ng_node_set_private(node_p node, void * val, 448307362Sbapt char *file, int line); 449270817Spluknetstatic __inline void * _ng_node_private(node_p node, char *file, int line); 450316350Sbaptstatic __inline int _ng_node_is_valid(node_p node, char *file, int line); 451316350Sbaptstatic __inline int _ng_node_not_valid(node_p node, char *file, int line); 452163302Srustatic __inline int _ng_node_numhooks(node_p node, char *file, int line); 453316350Sbaptstatic __inline void _ng_node_force_writer(node_p node, char *file, int line); 454163302Srustatic __inline hook_p _ng_node_foreach_hook(node_p node, 455163302Sru ng_fn_eachhook *fn, void *arg, char *file, int line); 456270817Spluknetstatic __inline void _ng_node_revive(node_p node, char *file, int line); 457307362Sbapt 458316350Sbaptstatic __inline void 459316350Sbapt_chknode(node_p node, char *file, int line) 460316350Sbapt{ 461163302Sru if (node->nd_magic != ND_MAGIC) { 462163302Sru printf("Accessing freed "); 463163302Sru dumpnode(node, file, line); 464163302Sru } 465270817Spluknet node->lastline = line; 466163302Sru node->lastfile = file; 467163302Sru} 468163302Sru 469270817Spluknetstatic __inline char * 470307362Sbapt_ng_node_name(node_p node, char *file, int line) 471316350Sbapt{ 472163302Sru _chknode(node, file, line); 473163302Sru return(_NG_NODE_NAME(node)); 474163302Sru} 475163302Sru 476200835Sedwinstatic __inline int 477200835Sedwin_ng_node_has_name(node_p node, char *file, int line) 478200835Sedwin{ 479200835Sedwin _chknode(node, file, line); 480200835Sedwin return(_NG_NODE_HAS_NAME(node)); 481200835Sedwin} 482200835Sedwin 483200835Sedwinstatic __inline ng_ID_t 484200835Sedwin_ng_node_id(node_p node, char *file, int line) 485200835Sedwin{ 486307362Sbapt _chknode(node, file, line); 487200835Sedwin return(_NG_NODE_ID(node)); 488270817Spluknet} 489200835Sedwin 490270817Spluknetstatic __inline void 491200835Sedwin_ng_node_ref(node_p node, char *file, int line) 492200835Sedwin{ 493200835Sedwin _chknode(node, file, line); 494200835Sedwin _NG_NODE_REF(node); 495200835Sedwin} 496200835Sedwin 497200835Sedwinstatic __inline void 498200835Sedwin_ng_node_unref(node_p node, char *file, int line) 499200835Sedwin{ 500200835Sedwin _chknode(node, file, line); 501200835Sedwin _NG_NODE_UNREF(node); 502200835Sedwin} 503200835Sedwin 504200835Sedwinstatic __inline void 505200835Sedwin_ng_node_set_private(node_p node, void * val, char *file, int line) 506200835Sedwin{ 507200835Sedwin _chknode(node, file, line); 508200835Sedwin _NG_NODE_SET_PRIVATE(node, val); 509200835Sedwin} 510200835Sedwin 511200835Sedwinstatic __inline void * 512270817Spluknet_ng_node_private(node_p node, char *file, int line) 513200835Sedwin{ 514200835Sedwin _chknode(node, file, line); 515200835Sedwin return (_NG_NODE_PRIVATE(node)); 516200835Sedwin} 517200835Sedwin 518200835Sedwinstatic __inline int 519200835Sedwin_ng_node_is_valid(node_p node, char *file, int line) 520200835Sedwin{ 521200835Sedwin _chknode(node, file, line); 522200835Sedwin return(_NG_NODE_IS_VALID(node)); 523200835Sedwin} 524270817Spluknet 525270817Spluknetstatic __inline int 526325160Sphilip_ng_node_not_valid(node_p node, char *file, int line) 527270817Spluknet{ 528270817Spluknet _chknode(node, file, line); 529270817Spluknet return(_NG_NODE_NOT_VALID(node)); 530270817Spluknet} 531270817Spluknet 532270817Spluknetstatic __inline int 533270817Spluknet_ng_node_numhooks(node_p node, char *file, int line) 534270817Spluknet{ 535270817Spluknet _chknode(node, file, line); 536270817Spluknet return(_NG_NODE_NUMHOOKS(node)); 537270817Spluknet} 538270817Spluknet 539270817Spluknetstatic __inline void 540270817Spluknet_ng_node_force_writer(node_p node, char *file, int line) 541270817Spluknet{ 542307362Sbapt _chknode(node, file, line); 543307362Sbapt _NG_NODE_FORCE_WRITER(node); 544270817Spluknet} 545270817Spluknet 546270817Spluknetstatic __inline void 547270817Spluknet_ng_node_hi_stack(node_p node, char *file, int line) 548270817Spluknet{ 549270817Spluknet _chknode(node, file, line); 550270817Spluknet _NG_NODE_HI_STACK(node); 551270817Spluknet} 552273719Sedwin 553270817Spluknetstatic __inline void 554270817Spluknet_ng_node_really_die(node_p node, char *file, int line) 555270817Spluknet{ 556270817Spluknet _chknode(node, file, line); 557307362Sbapt _NG_NODE_REALLY_DIE(node); 558270817Spluknet} 559307362Sbapt 560307362Sbaptstatic __inline void 561270817Spluknet_ng_node_revive(node_p node, char *file, int line) 562307362Sbapt{ 563270817Spluknet _chknode(node, file, line); 564270817Spluknet _NG_NODE_REVIVE(node); 565270817Spluknet} 566270817Spluknet 567339631Sphilipstatic __inline hook_p 56814343Swollman_ng_node_foreach_hook(node_p node, ng_fn_eachhook *fn, void *arg, 569270817Spluknet char *file, int line) 570270817Spluknet{ 571270817Spluknet hook_p hook; 572316350Sbapt _chknode(node, file, line); 57393799Swollman _NG_NODE_FOREACH_HOOK(node, fn, arg, hook); 574198825Sedwin return (hook); 575248307Sedwin} 576248307Sedwin 577248307Sedwin#define NG_NODE_NAME(node) _ng_node_name(node, _NN_) 578248307Sedwin#define NG_NODE_HAS_NAME(node) _ng_node_has_name(node, _NN_) 579198825Sedwin#define NG_NODE_ID(node) _ng_node_id(node, _NN_) 580200835Sedwin#define NG_NODE_REF(node) _ng_node_ref(node, _NN_) 581200835Sedwin#define NG_NODE_UNREF(node) _ng_node_unref(node, _NN_) 582198825Sedwin#define NG_NODE_SET_PRIVATE(node, val) _ng_node_set_private(node, val, _NN_) 583198825Sedwin#define NG_NODE_PRIVATE(node) _ng_node_private(node, _NN_) 584198825Sedwin#define NG_NODE_IS_VALID(node) _ng_node_is_valid(node, _NN_) 585198825Sedwin#define NG_NODE_NOT_VALID(node) _ng_node_not_valid(node, _NN_) 586198825Sedwin#define NG_NODE_FORCE_WRITER(node) _ng_node_force_writer(node, _NN_) 587198825Sedwin#define NG_NODE_HI_STACK(node) _ng_node_hi_stack(node, _NN_) 588198825Sedwin#define NG_NODE_REALLY_DIE(node) _ng_node_really_die(node, _NN_) 589342669Sphilip#define NG_NODE_NUMHOOKS(node) _ng_node_numhooks(node, _NN_) 590342669Sphilip#define NG_NODE_REVIVE(node) _ng_node_revive(node, _NN_) 591342669Sphilip#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 592342669Sphilip do { \ 593342669Sphilip rethook = _ng_node_foreach_hook(node, fn, (void *)arg, _NN_); \ 594342669Sphilip } while (0) 595342669Sphilip 596342669Sphilip#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 597342669Sphilip 598342669Sphilip#define NG_NODE_NAME(node) _NG_NODE_NAME(node) 599342669Sphilip#define NG_NODE_HAS_NAME(node) _NG_NODE_HAS_NAME(node) 600342669Sphilip#define NG_NODE_ID(node) _NG_NODE_ID(node) 601342669Sphilip#define NG_NODE_REF(node) _NG_NODE_REF(node) 602342669Sphilip#define NG_NODE_UNREF(node) _NG_NODE_UNREF(node) 603342669Sphilip#define NG_NODE_SET_PRIVATE(node, val) _NG_NODE_SET_PRIVATE(node, val) 604342669Sphilip#define NG_NODE_PRIVATE(node) _NG_NODE_PRIVATE(node) 605342669Sphilip#define NG_NODE_IS_VALID(node) _NG_NODE_IS_VALID(node) 606342669Sphilip#define NG_NODE_NOT_VALID(node) _NG_NODE_NOT_VALID(node) 607342669Sphilip#define NG_NODE_FORCE_WRITER(node) _NG_NODE_FORCE_WRITER(node) 608342669Sphilip#define NG_NODE_HI_STACK(node) _NG_NODE_HI_STACK(node) 609342669Sphilip#define NG_NODE_REALLY_DIE(node) _NG_NODE_REALLY_DIE(node) 610342669Sphilip#define NG_NODE_NUMHOOKS(node) _NG_NODE_NUMHOOKS(node) 611342669Sphilip#define NG_NODE_REVIVE(node) _NG_NODE_REVIVE(node) 612342669Sphilip#define NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) \ 613342669Sphilip _NG_NODE_FOREACH_HOOK(node, fn, arg, rethook) 614342669Sphilip#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 615342669Sphilip 616342669Sphilip/*********************************************************************** 617342669Sphilip ************* Node Queue and Item Structures and Methods ************** 618342669Sphilip *********************************************************************** 619342669Sphilip * 620342669Sphilip */ 621342669Sphiliptypedef void ng_item_fn(node_p node, hook_p hook, void *arg1, int arg2); 622342669Sphiliptypedef int ng_item_fn2(node_p node, struct ng_item *item, hook_p hook); 623342669Sphiliptypedef void ng_apply_t(void *context, int error); 624342669Sphilipstruct ng_apply_info { 625342669Sphilip ng_apply_t *apply; 626342669Sphilip void *context; 627342669Sphilip int refs; 628342669Sphilip int error; 629342669Sphilip}; 630342669Sphilipstruct ng_item { 631342669Sphilip u_long el_flags; 632342669Sphilip STAILQ_ENTRY(ng_item) el_next; 633342669Sphilip node_p el_dest; /* The node it will be applied against (or NULL) */ 634342669Sphilip hook_p el_hook; /* Entering hook. Optional in Control messages */ 635342669Sphilip union { 636342669Sphilip struct mbuf *da_m; 637342669Sphilip struct { 638342669Sphilip struct ng_mesg *msg_msg; 639342669Sphilip ng_ID_t msg_retaddr; 640342669Sphilip } msg; 641342669Sphilip struct { 642342669Sphilip union { 643342669Sphilip ng_item_fn *fn_fn; 644342669Sphilip ng_item_fn2 *fn_fn2; 645342669Sphilip } fn_fn; 646342669Sphilip void *fn_arg1; 647342669Sphilip int fn_arg2; 648342669Sphilip } fn; 649342669Sphilip } body; 650342669Sphilip /* 651342669Sphilip * Optional callback called when item is being applied, 652342669Sphilip * and its context. 653342669Sphilip */ 654342669Sphilip struct ng_apply_info *apply; 655342669Sphilip u_int depth; 656342669Sphilip#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 657342669Sphilip char *lastfile; 658342669Sphilip int lastline; 659342669Sphilip TAILQ_ENTRY(ng_item) all; /* all existing items */ 660198825Sedwin#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 661342669Sphilip}; 662342669Sphilip 663198825Sedwin#define NGQF_TYPE 0x03 /* MASK of content definition */ 664342669Sphilip#define NGQF_MESG 0x00 /* the queue element is a message */ 665240457Sedwin#define NGQF_DATA 0x01 /* the queue element is data */ 666198825Sedwin#define NGQF_FN 0x02 /* the queue element is a function */ 667198825Sedwin#define NGQF_FN2 0x03 /* the queue element is a new function */ 668198825Sedwin 669198825Sedwin#define NGQF_RW 0x04 /* MASK for wanted queue mode */ 670198825Sedwin#define NGQF_READER 0x04 /* wants to be a reader */ 671198825Sedwin#define NGQF_WRITER 0x00 /* wants to be a writer */ 672198825Sedwin 673198825Sedwin#define NGQF_QMODE 0x08 /* MASK for how it was queued */ 674198825Sedwin#define NGQF_QREADER 0x08 /* was queued as a reader */ 675342669Sphilip#define NGQF_QWRITER 0x00 /* was queued as a writer */ 676198825Sedwin 677198825Sedwin/* 678198825Sedwin * Get the mbuf (etc) out of an item. 679198825Sedwin * Sets the value in the item to NULL in case we need to call NG_FREE_ITEM() 680198825Sedwin * with it, (to avoid freeing the things twice). 681198825Sedwin * If you don't want to zero out the item then realise that the 682198825Sedwin * item still owns it. 683198825Sedwin * Retaddr is different. There are no references on that. It's just a number. 684198825Sedwin * The debug versions must be either all used everywhere or not at all. 685198825Sedwin */ 686198825Sedwin 687198825Sedwin#define _NGI_M(i) ((i)->body.da_m) 688198825Sedwin#define _NGI_MSG(i) ((i)->body.msg.msg_msg) 689198825Sedwin#define _NGI_RETADDR(i) ((i)->body.msg.msg_retaddr) 690198825Sedwin#define _NGI_FN(i) ((i)->body.fn.fn_fn.fn_fn) 691198825Sedwin#define _NGI_FN2(i) ((i)->body.fn.fn_fn.fn_fn2) 692198825Sedwin#define _NGI_ARG1(i) ((i)->body.fn.fn_arg1) 693198825Sedwin#define _NGI_ARG2(i) ((i)->body.fn.fn_arg2) 694198825Sedwin#define _NGI_NODE(i) ((i)->el_dest) 695198825Sedwin#define _NGI_HOOK(i) ((i)->el_hook) 696198825Sedwin#define _NGI_SET_HOOK(i,h) do { _NGI_HOOK(i) = h; h = NULL;} while (0) 697198825Sedwin#define _NGI_CLR_HOOK(i) do { \ 698198825Sedwin hook_p _hook = _NGI_HOOK(i); \ 699198825Sedwin if (_hook) { \ 700198825Sedwin _NG_HOOK_UNREF(_hook); \ 701198825Sedwin _NGI_HOOK(i) = NULL; \ 702198825Sedwin } \ 703198825Sedwin } while (0) 704342669Sphilip#define _NGI_SET_NODE(i,n) do { _NGI_NODE(i) = n; n = NULL;} while (0) 705342669Sphilip#define _NGI_CLR_NODE(i) do { \ 706342669Sphilip node_p _node = _NGI_NODE(i); \ 707342669Sphilip if (_node) { \ 708342669Sphilip _NG_NODE_UNREF(_node); \ 709342669Sphilip _NGI_NODE(i) = NULL; \ 710342669Sphilip } \ 711342669Sphilip } while (0) 712342669Sphilip 713198825Sedwin#ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ 7142742Swollmanvoid dumpitem(item_p item, char *file, int line); 7152742Swollmanstatic __inline void _ngi_check(item_p item, char *file, int line) ; 7162742Swollmanstatic __inline struct mbuf ** _ngi_m(item_p item, char *file, int line) ; 7172742Swollmanstatic __inline ng_ID_t * _ngi_retaddr(item_p item, char *file, int line); 7182742Swollmanstatic __inline struct ng_mesg ** _ngi_msg(item_p item, char *file, int line) ; 7192742Swollmanstatic __inline ng_item_fn ** _ngi_fn(item_p item, char *file, int line) ; 720198825Sedwinstatic __inline ng_item_fn2 ** _ngi_fn2(item_p item, char *file, int line) ; 721342669Sphilipstatic __inline void ** _ngi_arg1(item_p item, char *file, int line) ; 7222742Swollmanstatic __inline int * _ngi_arg2(item_p item, char *file, int line) ; 7232742Swollmanstatic __inline node_p _ngi_node(item_p item, char *file, int line); 7242742Swollmanstatic __inline hook_p _ngi_hook(item_p item, char *file, int line); 7252742Swollman 726213312Sedwinstatic __inline void 727213312Sedwin_ngi_check(item_p item, char *file, int line) 728198825Sedwin{ 729198825Sedwin (item)->lastline = line; 730198825Sedwin (item)->lastfile = file; 7312742Swollman} 732342669Sphilip 733342669Sphilipstatic __inline struct mbuf ** 734342669Sphilip_ngi_m(item_p item, char *file, int line) 735342669Sphilip{ 736342669Sphilip _ngi_check(item, file, line); 73758787Sru return (&_NGI_M(item)); 7382742Swollman} 73930711Swollman 74030711Swollmanstatic __inline struct ng_mesg ** 74143014Swollman_ngi_msg(item_p item, char *file, int line) 74230711Swollman{ 743206868Sedwin _ngi_check(item, file, line); 744270817Spluknet return (&_NGI_MSG(item)); 745206868Sedwin} 746206868Sedwin 747206868Sedwinstatic __inline ng_ID_t * 748270817Spluknet_ngi_retaddr(item_p item, char *file, int line) 749270817Spluknet{ 750270817Spluknet _ngi_check(item, file, line); 751270817Spluknet return (&_NGI_RETADDR(item)); 752270817Spluknet} 753270817Spluknet 754270817Spluknetstatic __inline ng_item_fn ** 755325160Sphilip_ngi_fn(item_p item, char *file, int line) 756270817Spluknet{ 757270817Spluknet _ngi_check(item, file, line); 758270817Spluknet return (&_NGI_FN(item)); 759270817Spluknet} 760270817Spluknet 761270817Spluknetstatic __inline ng_item_fn2 ** 762270817Spluknet_ngi_fn2(item_p item, char *file, int line) 763270817Spluknet{ 764270817Spluknet _ngi_check(item, file, line); 765270817Spluknet return (&_NGI_FN2(item)); 766328476Sphilip} 767270817Spluknet 768325160Sphilipstatic __inline void ** 769270817Spluknet_ngi_arg1(item_p item, char *file, int line) 770328476Sphilip{ 771206868Sedwin _ngi_check(item, file, line); 772270817Spluknet return (&_NGI_ARG1(item)); 773328476Sphilip} 774328476Sphilip 775270817Spluknetstatic __inline int * 776328476Sphilip_ngi_arg2(item_p item, char *file, int line) 777270817Spluknet{ 778270817Spluknet _ngi_check(item, file, line); 779270817Spluknet return (&_NGI_ARG2(item)); 780270817Spluknet} 781270817Spluknet 782270817Spluknetstatic __inline node_p 783270817Spluknet_ngi_node(item_p item, char *file, int line) 784270817Spluknet{ 785270817Spluknet _ngi_check(item, file, line); 786270817Spluknet return (_NGI_NODE(item)); 787270817Spluknet} 788270817Spluknet 789270817Spluknetstatic __inline hook_p 790270817Spluknet_ngi_hook(item_p item, char *file, int line) 791270817Spluknet{ 792270817Spluknet _ngi_check(item, file, line); 793270817Spluknet return (_NGI_HOOK(item)); 794270817Spluknet} 795270817Spluknet 796270817Spluknet#define NGI_M(i) (*_ngi_m(i, _NN_)) 797270817Spluknet#define NGI_MSG(i) (*_ngi_msg(i, _NN_)) 798270817Spluknet#define NGI_RETADDR(i) (*_ngi_retaddr(i, _NN_)) 799270817Spluknet#define NGI_FN(i) (*_ngi_fn(i, _NN_)) 800270817Spluknet#define NGI_FN2(i) (*_ngi_fn2(i, _NN_)) 801270817Spluknet#define NGI_ARG1(i) (*_ngi_arg1(i, _NN_)) 802270817Spluknet#define NGI_ARG2(i) (*_ngi_arg2(i, _NN_)) 803270817Spluknet#define NGI_HOOK(i) _ngi_hook(i, _NN_) 804270817Spluknet#define NGI_NODE(i) _ngi_node(i, _NN_) 805270817Spluknet#define NGI_SET_HOOK(i,h) \ 806270817Spluknet do { _ngi_check(i, _NN_); _NGI_SET_HOOK(i, h); } while (0) 807270817Spluknet#define NGI_CLR_HOOK(i) \ 808270817Spluknet do { _ngi_check(i, _NN_); _NGI_CLR_HOOK(i); } while (0) 809270817Spluknet#define NGI_SET_NODE(i,n) \ 810270817Spluknet do { _ngi_check(i, _NN_); _NGI_SET_NODE(i, n); } while (0) 811270817Spluknet#define NGI_CLR_NODE(i) \ 812270817Spluknet do { _ngi_check(i, _NN_); _NGI_CLR_NODE(i); } while (0) 813270817Spluknet 814270817Spluknet#define NG_FREE_ITEM(item) \ 815270817Spluknet do { \ 816270817Spluknet _ngi_check(item, _NN_); \ 817270817Spluknet ng_free_item((item)); \ 818270817Spluknet } while (0) 819270817Spluknet 820270817Spluknet#define SAVE_LINE(item) \ 821273719Sedwin do { \ 822273719Sedwin (item)->lastline = __LINE__; \ 823270817Spluknet (item)->lastfile = __FILE__; \ 824270817Spluknet } while (0) 825270817Spluknet 826270817Spluknet#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 827273719Sedwin 828270817Spluknet#define NGI_M(i) _NGI_M(i) 829270817Spluknet#define NGI_MSG(i) _NGI_MSG(i) 830270817Spluknet#define NGI_RETADDR(i) _NGI_RETADDR(i) 831270817Spluknet#define NGI_FN(i) _NGI_FN(i) 832270817Spluknet#define NGI_FN2(i) _NGI_FN2(i) 833273719Sedwin#define NGI_ARG1(i) _NGI_ARG1(i) 834270817Spluknet#define NGI_ARG2(i) _NGI_ARG2(i) 835270817Spluknet#define NGI_NODE(i) _NGI_NODE(i) 836270817Spluknet#define NGI_HOOK(i) _NGI_HOOK(i) 837270817Spluknet#define NGI_SET_HOOK(i,h) _NGI_SET_HOOK(i,h) 838270817Spluknet#define NGI_CLR_HOOK(i) _NGI_CLR_HOOK(i) 839307362Sbapt#define NGI_SET_NODE(i,n) _NGI_SET_NODE(i,n) 840270817Spluknet#define NGI_CLR_NODE(i) _NGI_CLR_NODE(i) 841270817Spluknet 842270817Spluknet#define NG_FREE_ITEM(item) ng_free_item((item)) 84330711Swollman#define SAVE_LINE(item) do {} while (0) 844270817Spluknet 845270817Spluknet#endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ 846270817Spluknet 847270817Spluknet#define NGI_GET_M(i,m) \ 848270817Spluknet do { \ 849270817Spluknet (m) = NGI_M(i); \ 85030711Swollman _NGI_M(i) = NULL; \ 85130711Swollman } while (0) 85230711Swollman 85330711Swollman#define NGI_GET_MSG(i,m) \ 85430711Swollman do { \ 85530711Swollman (m) = NGI_MSG(i); \ 85630711Swollman _NGI_MSG(i) = NULL; \ 857270817Spluknet } while (0) 858270817Spluknet 859206868Sedwin#define NGI_GET_NODE(i,n) /* YOU NOW HAVE THE REFERENCE */ \ 86030711Swollman do { \ 861270817Spluknet (n) = NGI_NODE(i); \ 862270817Spluknet _NGI_NODE(i) = NULL; \ 863316350Sbapt } while (0) 864273719Sedwin 86530711Swollman#define NGI_GET_HOOK(i,h) \ 86630711Swollman do { \ 86793799Swollman (h) = NGI_HOOK(i); \ 868339631Sphilip _NGI_HOOK(i) = NULL; \ 869339631Sphilip } while (0) 870339631Sphilip 871339631Sphilip#define NGI_SET_WRITER(i) ((i)->el_flags &= ~NGQF_QMODE) 872339631Sphilip#define NGI_SET_READER(i) ((i)->el_flags |= NGQF_QREADER) 873339631Sphilip 874339631Sphilip#define NGI_QUEUED_READER(i) ((i)->el_flags & NGQF_QREADER) 875339631Sphilip#define NGI_QUEUED_WRITER(i) (((i)->el_flags & NGQF_QMODE) == NGQF_QWRITER) 876339631Sphilip 877339631Sphilip/********************************************************************** 878339631Sphilip* Data macros. Send, manipulate and free. 879339631Sphilip**********************************************************************/ 880339631Sphilip/* 881339631Sphilip * Assuming the data is already ok, just set the new address and send 882339631Sphilip */ 883339631Sphilip#define NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags) \ 884339631Sphilip do { \ 885339631Sphilip (error) = \ 886339631Sphilip ng_address_hook(NULL, (item), (hook), NG_NOFLAGS); \ 887339631Sphilip if (error == 0) { \ 888339631Sphilip SAVE_LINE(item); \ 889339631Sphilip (error) = ng_snd_item((item), (flags)); \ 890339631Sphilip } \ 891339631Sphilip (item) = NULL; \ 892339631Sphilip } while (0) 893339631Sphilip#define NG_FWD_ITEM_HOOK(error, item, hook) \ 894339631Sphilip NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, NG_NOFLAGS) 895339631Sphilip 896339631Sphilip/* 897339631Sphilip * Forward a data packet. Mbuf pointer is updated to new value. We 898339631Sphilip * presume you dealt with the old one when you update it to the new one 899339631Sphilip * (or it maybe the old one). We got a packet and possibly had to modify 900339631Sphilip * the mbuf. You should probably use NGI_GET_M() if you are going to use 901339631Sphilip * this too. 902339631Sphilip */ 903339631Sphilip#define NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, flags) \ 904339631Sphilip do { \ 905339631Sphilip NGI_M(item) = (m); \ 906339631Sphilip (m) = NULL; \ 907339631Sphilip NG_FWD_ITEM_HOOK_FLAGS(error, item, hook, flags); \ 908339631Sphilip } while (0) 909339631Sphilip#define NG_FWD_NEW_DATA(error, item, hook, m) \ 910339631Sphilip NG_FWD_NEW_DATA_FLAGS(error, item, hook, m, NG_NOFLAGS) 911339631Sphilip 912339631Sphilip/* Send a previously unpackaged mbuf. XXX: This should be called 913339631Sphilip * NG_SEND_DATA in future, but this name is kept for compatibility 914339631Sphilip * reasons. 915339631Sphilip */ 916339631Sphilip#define NG_SEND_DATA_FLAGS(error, hook, m, flags) \ 917339631Sphilip do { \ 918339631Sphilip item_p _item; \ 919339631Sphilip if ((_item = ng_package_data((m), flags))) { \ 920339631Sphilip NG_FWD_ITEM_HOOK_FLAGS(error, _item, hook, flags);\ 921339631Sphilip } else { \ 922339631Sphilip (error) = ENOMEM; \ 923339631Sphilip } \ 924339631Sphilip (m) = NULL; \ 925339631Sphilip } while (0) 926339631Sphilip 927339631Sphilip#define NG_SEND_DATA_ONLY(error, hook, m) \ 928339631Sphilip NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS) 929339631Sphilip/* NG_SEND_DATA() compat for meta-data times */ 930339631Sphilip#define NG_SEND_DATA(error, hook, m, x) \ 931339631Sphilip NG_SEND_DATA_FLAGS(error, hook, m, NG_NOFLAGS) 932339631Sphilip 933339631Sphilip#define NG_FREE_MSG(msg) \ 934339631Sphilip do { \ 935339631Sphilip if ((msg)) { \ 936339631Sphilip free((msg), M_NETGRAPH_MSG); \ 937339631Sphilip (msg) = NULL; \ 938339631Sphilip } \ 939339631Sphilip } while (0) 940339631Sphilip 941339631Sphilip#define NG_FREE_M(m) \ 942339631Sphilip do { \ 943339631Sphilip if ((m)) { \ 944339631Sphilip m_freem((m)); \ 945339631Sphilip (m) = NULL; \ 946339631Sphilip } \ 947339631Sphilip } while (0) 948339631Sphilip 949339631Sphilip/***************************************** 950339631Sphilip* Message macros 951339631Sphilip*****************************************/ 952339631Sphilip 953339631Sphilip#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr) \ 954339631Sphilip do { \ 955339631Sphilip item_p _item; \ 956339631Sphilip if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 957339631Sphilip (msg) = NULL; \ 958339631Sphilip (error) = ENOMEM; \ 959339631Sphilip break; \ 960339631Sphilip } \ 961339631Sphilip if (((error) = ng_address_hook((here), (_item), \ 962339631Sphilip (hook), (retaddr))) == 0) { \ 963339631Sphilip SAVE_LINE(_item); \ 964339631Sphilip (error) = ng_snd_item((_item), 0); \ 965339631Sphilip } \ 966339631Sphilip (msg) = NULL; \ 967339631Sphilip } while (0) 968339631Sphilip 9692742Swollman#define NG_SEND_MSG_PATH(error, here, msg, path, retaddr) \ 970339631Sphilip do { \ 971339631Sphilip item_p _item; \ 972339631Sphilip if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 973339631Sphilip (msg) = NULL; \ 974339631Sphilip (error) = ENOMEM; \ 975339631Sphilip break; \ 976339631Sphilip } \ 977339631Sphilip if (((error) = ng_address_path((here), (_item), \ 978339631Sphilip (path), (retaddr))) == 0) { \ 979339631Sphilip SAVE_LINE(_item); \ 980339631Sphilip (error) = ng_snd_item((_item), 0); \ 981339631Sphilip } \ 982339631Sphilip (msg) = NULL; \ 983339631Sphilip } while (0) 984339631Sphilip 985339631Sphilip#define NG_SEND_MSG_ID(error, here, msg, ID, retaddr) \ 986339631Sphilip do { \ 987339631Sphilip item_p _item; \ 988339631Sphilip if ((_item = ng_package_msg(msg, NG_NOFLAGS)) == NULL) {\ 989339631Sphilip (msg) = NULL; \ 990339631Sphilip (error) = ENOMEM; \ 991339631Sphilip break; \ 992339631Sphilip } \ 993339631Sphilip if (((error) = ng_address_ID((here), (_item), \ 994339631Sphilip (ID), (retaddr))) == 0) { \ 995339631Sphilip SAVE_LINE(_item); \ 996339631Sphilip (error) = ng_snd_item((_item), 0); \ 997339631Sphilip } \ 9982742Swollman (msg) = NULL; \ 999339631Sphilip } while (0) 1000339631Sphilip 1001339631Sphilip/* 1002316350Sbapt * Redirect the message to the next hop using the given hook. 10032742Swollman * ng_retarget_msg() frees the item if there is an error 10042742Swollman * and returns an error code. It returns 0 on success. 10052742Swollman */ 10062742Swollman#define NG_FWD_MSG_HOOK(error, here, item, hook, retaddr) \ 10072742Swollman do { \ 1008308302Sgjb if (((error) = ng_address_hook((here), (item), \ 1009248307Sedwin (hook), (retaddr))) == 0) { \ 1010308302Sgjb SAVE_LINE(item); \ 1011308302Sgjb (error) = ng_snd_item((item), 0); \ 1012308302Sgjb } \ 1013308302Sgjb (item) = NULL; \ 1014308302Sgjb } while (0) 1015308302Sgjb 1016248307Sedwin/* 1017308302Sgjb * Send a queue item back to it's originator with a response message. 1018308302Sgjb * Assume original message was removed and freed separatly. 1019308302Sgjb */ 1020308302Sgjb#define NG_RESPOND_MSG(error, here, item, resp) \ 1021325160Sphilip do { \ 1022325160Sphilip if (resp) { \ 1023325160Sphilip ng_ID_t _dest = NGI_RETADDR(item); \ 1024325160Sphilip NGI_RETADDR(item) = 0; \ 1025325160Sphilip NGI_MSG(item) = resp; \ 1026325160Sphilip if ((error = ng_address_ID((here), (item), \ 10272742Swollman _dest, 0)) == 0) { \ 102819878Swollman SAVE_LINE(item); \ 10292742Swollman (error) = ng_snd_item((item), NG_QUEUE);\ 103019878Swollman } \ 10312742Swollman } else \ 103219878Swollman NG_FREE_ITEM(item); \ 10332742Swollman (item) = NULL; \ 10342742Swollman } while (0) 103543543Swollman 103643543Swollman 10372742Swollman/*********************************************************************** 10382742Swollman ******** Structures Definitions and Macros for defining a node ******* 103943543Swollman *********************************************************************** 104058787Sru * 1041308302Sgjb * Here we define the structures needed to actually define a new node 1042308302Sgjb * type. 1043308302Sgjb */ 1044325160Sphilip 1045325160Sphilip/* 10462742Swollman * Command list -- each node type specifies the command that it knows 104767578Swollman * how to convert between ASCII and binary using an array of these. 104867578Swollman * The last element in the array must be a terminator with cookie=0. 104967578Swollman */ 105067578Swollman 10512742Swollmanstruct ng_cmdlist { 1052149514Swollman u_int32_t cookie; /* command typecookie */ 10539908Swollman int cmd; /* command number */ 10549908Swollman const char *name; /* command name */ 10559908Swollman const struct ng_parse_type *mesgType; /* args if !NGF_RESP */ 105614343Swollman const struct ng_parse_type *respType; /* args if NGF_RESP */ 105714343Swollman}; 1058149514Swollman 105920094Swollman/* 106020094Swollman * Structure of a node type 106120094Swollman * If data is sent to the "rcvdata()" entrypoint then the system 1062136638Swollman * may decide to defer it until later by queing it with the normal netgraph 1063136638Swollman * input queuing system. This is decidde by the HK_QUEUE flag being set in 1064149514Swollman * the flags word of the peer (receiving) hook. The dequeuing mechanism will 1065136638Swollman * ensure it is not requeued again. 1066136638Swollman * Note the input queueing system is to allow modules 1067136638Swollman * to 'release the stack' or to pass data across spl layers. 1068136638Swollman * The data will be redelivered as soon as the NETISR code runs 1069270817Spluknet * which may be almost immediatly. A node may also do it's own queueing 1070136638Swollman * for other reasons (e.g. device output queuing). 1071136638Swollman */ 1072153670Swollmanstruct ng_type { 1073153670Swollman 1074153670Swollman u_int32_t version; /* must equal NG_API_VERSION */ 1075153670Swollman const char *name; /* Unique type name */ 1076153670Swollman modeventhand_t mod_event; /* Module event handler (optional) */ 1077153670Swollman ng_constructor_t *constructor; /* Node constructor */ 1078153670Swollman ng_rcvmsg_t *rcvmsg; /* control messages come here */ 1079153670Swollman ng_close_t *close; /* warn about forthcoming shutdown */ 1080153670Swollman ng_shutdown_t *shutdown; /* reset, and free resources */ 1081153670Swollman ng_newhook_t *newhook; /* first notification of new hook */ 1082273719Sedwin ng_findhook_t *findhook; /* only if you have lots of hooks */ 1083273719Sedwin ng_connect_t *connect; /* final notification of new hook */ 1084273719Sedwin ng_rcvdata_t *rcvdata; /* data comes here */ 1085153670Swollman ng_disconnect_t *disconnect; /* notify on disconnect */ 10862742Swollman 1087273719Sedwin const struct ng_cmdlist *cmdlist; /* commands we can convert */ 1088273719Sedwin 1089307362Sbapt /* R/W data private to the base netgraph code DON'T TOUCH! */ 1090307362Sbapt LIST_ENTRY(ng_type) types; /* linked list of all types */ 1091307362Sbapt int refs; /* number of instances */ 1092307362Sbapt}; 1093307362Sbapt 1094307362Sbapt/* 1095307362Sbapt * Use the NETGRAPH_INIT() macro to link a node type into the 1096307362Sbapt * netgraph system. This works for types compiled into the kernel 1097307362Sbapt * as well as KLD modules. The first argument should be the type 10982742Swollman * name (eg, echo) and the second a pointer to the type struct. 109958787Sru * 110075267Swollman * If a different link time is desired, e.g., a device driver that 1101169811Swollman * needs to install its netgraph type before probing, use the 1102169811Swollman * NETGRAPH_INIT_ORDERED() macro instead. Device drivers probably 1103270817Spluknet * want to use SI_SUB_DRIVERS/SI_ORDER_FIRST. 110475267Swollman */ 1105325160Sphilip 110675267Swollman#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \ 110775267Swollmanstatic moduledata_t ng_##typename##_mod = { \ 110875267Swollman "ng_" #typename, \ 110975267Swollman ng_mod_event, \ 111075267Swollman (typestructp) \ 111175267Swollman}; \ 111275267SwollmanDECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \ 111375267SwollmanMODULE_DEPEND(ng_##typename, netgraph, NG_ABI_VERSION, \ 111475267Swollman NG_ABI_VERSION, \ 111575267Swollman NG_ABI_VERSION) 1116270817Spluknet 1117270817Spluknet#define NETGRAPH_INIT(tn, tp) \ 111875267Swollman NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_MIDDLE) 111975267Swollman 112075267Swollman/* Special malloc() type for netgraph structs and ctrl messages */ 112175267Swollman/* Only these two types should be visible to nodes */ 112275267SwollmanMALLOC_DECLARE(M_NETGRAPH); 112358787SruMALLOC_DECLARE(M_NETGRAPH_MSG); 1124273719Sedwin 1125316350Sbapt/* declare the base of the netgraph sysclt hierarchy */ 1126316350Sbapt/* but only if this file cares about sysctls */ 1127316350Sbapt#ifdef SYSCTL_DECL 1128316350SbaptSYSCTL_DECL(_net_graph); 112958787Sru#endif 11302742Swollman 1131307362Sbapt/* 1132342669Sphilip * Methods that the nodes can use. 1133342669Sphilip * Many of these methods should usually NOT be used directly but via 1134342669Sphilip * Macros above. 1135342669Sphilip */ 1136342669Sphilipint ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr); 1137342669Sphilipint ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr); 1138342669Sphilipint ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr); 1139342669Sphilipint ng_bypass(hook_p hook1, hook_p hook2); 1140342669Sphiliphook_p ng_findhook(node_p node, const char *name); 1141342669Sphilipstruct ng_type *ng_findtype(const char *type); 1142307362Sbaptint ng_make_node_common(struct ng_type *typep, node_p *nodep); 1143325160Sphilipint ng_name_node(node_p node, const char *name); 1144307362Sbaptnode_p ng_name2noderef(node_p node, const char *name); 1145307362Sbaptint ng_newtype(struct ng_type *tp); 1146307362Sbaptng_ID_t ng_node2ID(node_p node); 1147307362Sbaptitem_p ng_package_data(struct mbuf *m, int flags); 1148307362Sbaptitem_p ng_package_msg(struct ng_mesg *msg, int flags); 1149307362Sbaptitem_p ng_package_msg_self(node_p here, hook_p hook, struct ng_mesg *msg); 1150325160Sphilipvoid ng_replace_retaddr(node_p here, item_p item, ng_ID_t retaddr); 1151325160Sphilipint ng_rmhook_self(hook_p hook); /* if a node wants to kill a hook */ 1152325160Sphilipint ng_rmnode_self(node_p here); /* if a node wants to suicide */ 1153325160Sphilipint ng_rmtype(struct ng_type *tp); 1154325160Sphilipint ng_snd_item(item_p item, int queue); 1155325160Sphilipint ng_send_fn(node_p node, hook_p hook, ng_item_fn *fn, void *arg1, 1156325160Sphilip int arg2); 1157325160Sphilipint ng_send_fn1(node_p node, hook_p hook, ng_item_fn *fn, void *arg1, 1158325160Sphilip int arg2, int flags); 1159325160Sphilipint ng_send_fn2(node_p node, hook_p hook, item_p pitem, ng_item_fn2 *fn, 1160325160Sphilip void *arg1, int arg2, int flags); 1161325160Sphilipint ng_uncallout(struct callout *c, node_p node); 1162325160Sphilipint ng_callout(struct callout *c, node_p node, hook_p hook, int ticks, 1163325160Sphilip ng_item_fn *fn, void * arg1, int arg2); 1164325160Sphilip#define ng_callout_init(c) callout_init(c, 1) 1165325160Sphilip 1166325160Sphilip/* Flags for netgraph functions. */ 1167325160Sphilip#define NG_NOFLAGS 0x00000000 /* no special options */ 1168325160Sphilip#define NG_QUEUE 0x00000001 /* enqueue item, don't dispatch */ 1169325160Sphilip#define NG_WAITOK 0x00000002 /* use M_WAITOK, etc. */ 1170325160Sphilip/* XXXGL: NG_PROGRESS unused since ng_base.c rev. 1.136. Should be deleted? */ 1171325160Sphilip#define NG_PROGRESS 0x00000004 /* return EINPROGRESS if queued */ 1172325160Sphilip#define NG_REUSE_ITEM 0x00000008 /* supplied item should be reused */ 1173325160Sphilip 1174325160Sphilip/* 1175325160Sphilip * prototypes the user should DEFINITELY not use directly 1176325160Sphilip */ 1177325160Sphilipvoid ng_free_item(item_p item); /* Use NG_FREE_ITEM instead */ 1178325160Sphilipint ng_mod_event(module_t mod, int what, void *arg); 1179325160Sphilip 1180325160Sphilip/* 1181325160Sphilip * Tag definitions and constants 1182325160Sphilip */ 1183325160Sphilip 1184325160Sphilip#define NG_TAG_PRIO 1 1185325160Sphilip 1186325160Sphilipstruct ng_tag_prio { 1187325160Sphilip struct m_tag tag; 1188325160Sphilip char priority; 11892742Swollman char discardability; 1190325160Sphilip}; 1191325160Sphilip 1192325160Sphilip#define NG_PRIO_CUTOFF 32 1193325160Sphilip#define NG_PRIO_LINKSTATE 64 1194325160Sphilip 11952742Swollman/* Macros and declarations to keep compatibility with metadata, which 1196316350Sbapt * is obsoleted now. To be deleted. 11972742Swollman */ 1198325160Sphiliptypedef void *meta_p; 11992742Swollman#define _NGI_META(i) NULL 12002742Swollman#define NGI_META(i) NULL 12012742Swollman#define NG_FREE_META(meta) 12022742Swollman#define NGI_GET_META(i,m) 12032742Swollman#define ng_copy_meta(meta) NULL 120486222Swollman 1205273719Sedwin/* 1206273719Sedwin * Mark the current thread when called from the outbound path of the 1207273719Sedwin * network stack, in order to enforce queuing on ng nodes calling into 1208273719Sedwin * the inbound network stack path. 1209158421Swollman */ 1210273719Sedwin#define NG_OUTBOUND_THREAD_REF() \ 121186222Swollman curthread->td_ng_outbound++ 121286222Swollman#define NG_OUTBOUND_THREAD_UNREF() \ 121386222Swollman do { \ 121486222Swollman curthread->td_ng_outbound--; \ 1215169811Swollman KASSERT(curthread->td_ng_outbound >= 0, \ 1216169811Swollman ("%s: negative td_ng_outbound", __func__)); \ 1217169811Swollman } while (0) 1218169811Swollman 1219169811Swollman#endif /* _NETGRAPH_NETGRAPH_H_ */ 1220169811Swollman