1 2/* 3 * netgraph.h 4 * 5 * Copyright (c) 1996-1999 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and 9 * redistribution of this software, in source or object code forms, with or 10 * without modifications are expressly permitted by Whistle Communications; 11 * provided, however, that: 12 * 1. Any and all reproductions of the source or object code must include the 13 * copyright notice above and the following disclaimer of warranties; and 14 * 2. No rights are granted, in any manner or form, to use Whistle 15 * Communications, Inc. trademarks, including the mark "WHISTLE 16 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 17 * such appears in the above copyright notice or in the software. 18 * 19 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 20 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 21 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 22 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 24 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 25 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 26 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 27 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 28 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 29 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 30 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Author: Julian Elischer <julian@freebsd.org> 38 *
|
40 * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $ 41 */ 42 43#ifndef _NETGRAPH_NETGRAPH_H_ 44#define _NETGRAPH_NETGRAPH_H_ 1 45 46#include <sys/queue.h> 47#include <sys/malloc.h> 48#include <sys/module.h> 49 50#ifndef _KERNEL 51#error "This file should not be included in user level programs" 52#endif 53 54/* 55 * Structure of a hook 56 */ 57struct ng_hook { 58 char *name; /* what this node knows this link as */ 59 void *private; /* node dependant ID for this hook */ 60 int flags; /* info about this hook/link */ 61 int refs; /* dont actually free this till 0 */ 62 struct ng_hook *peer; /* the other end of this link */ 63 struct ng_node *node; /* The node this hook is attached to */ 64 LIST_ENTRY(ng_hook) hooks; /* linked list of all hooks on node */ 65}; 66typedef struct ng_hook *hook_p; 67 68/* Flags for a hook */ 69#define HK_INVALID 0x0001 /* don't trust it! */ 70#define HK_QUEUE 0x0002 /* queue for later delivery */ 71 72/* 73 * Structure of a node 74 */ 75struct ng_node { 76 char *name; /* optional globally unique name */ 77 struct ng_type *type; /* the installed 'type' */ 78 int flags; /* see below for bit definitions */ 79 int sleepers; /* #procs sleeping on this node */ 80 int refs; /* number of references to this node */ 81 int numhooks; /* number of hooks */ 82 int colour; /* for graph colouring algorithms */ 83 void *private; /* node type dependant node ID */ 84 ng_ID_t ID; /* Unique per node */ 85 LIST_HEAD(hooks, ng_hook) hooks; /* linked list of node hooks */ 86 LIST_ENTRY(ng_node) nodes; /* linked list of all nodes */ 87 LIST_ENTRY(ng_node) idnodes; /* ID hash collision list */ 88}; 89typedef struct ng_node *node_p; 90 91/* Flags for a node */ 92#define NG_INVALID 0x001 /* free when all sleepers and refs go to 0 */ 93#define NG_BUSY 0x002 /* callers should sleep or wait */ 94#define NG_TOUCHED 0x004 /* to avoid cycles when 'flooding' */ 95#define NGF_TYPE1 0x10000000 /* reserved for type specific storage */ 96#define NGF_TYPE2 0x20000000 /* reserved for type specific storage */ 97#define NGF_TYPE3 0x40000000 /* reserved for type specific storage */ 98#define NGF_TYPE4 0x80000000 /* reserved for type specific storage */ 99 100/* 101 * The structure that holds meta_data about a data packet (e.g. priority) 102 * Nodes might add or subtract options as needed if there is room. 103 * They might reallocate the struct to make more room if they need to. 104 * Meta-data is still experimental. 105 */ 106struct meta_field_header { 107 u_long cookie; /* cookie for the field. Skip fields you don't 108 * know about (same cookie as in messgaes) */ 109 u_short type; /* field ID */ 110 u_short len; /* total len of this field including extra 111 * data */ 112 char data[0]; /* data starts here */ 113}; 114 115/* To zero out an option 'in place' set it's cookie to this */ 116#define NGM_INVALID_COOKIE 865455152 117 118/* This part of the metadata is always present if the pointer is non NULL */ 119struct ng_meta { 120 char priority; /* -ve is less priority, 0 is default */ 121 char discardability; /* higher is less valuable.. discard first */ 122 u_short allocated_len; /* amount malloc'd */ 123 u_short used_len; /* sum of all fields, options etc. */ 124 u_short flags; /* see below.. generic flags */ 125 struct meta_field_header options[0]; /* add as (if) needed */ 126}; 127typedef struct ng_meta *meta_p; 128 129/* Flags for meta-data */ 130#define NGMF_TEST 0x01 /* discard at the last moment before sending */ 131#define NGMF_TRACE 0x02 /* trace when handing this data to a node */ 132 133/* node method definitions */ 134typedef int ng_constructor_t(node_p *node); 135typedef int ng_rcvmsg_t(node_p node, struct ng_mesg *msg, 136 const char *retaddr, struct ng_mesg **resp, 137 hook_p lasthook); 138typedef int ng_shutdown_t(node_p node); 139typedef int ng_newhook_t(node_p node, hook_p hook, const char *name); 140typedef hook_p ng_findhook_t(node_p node, const char *name); 141typedef int ng_connect_t(hook_p hook); 142typedef int ng_rcvdata_t(hook_p hook, struct mbuf *m, meta_p meta, 143 struct mbuf **ret_m, meta_p *ret_meta, struct ng_mesg **resp); 144typedef int ng_disconnect_t(hook_p hook); 145 146/* 147 * Command list -- each node type specifies the command that it knows 148 * how to convert between ASCII and binary using an array of these. 149 * The last element in the array must be a terminator with cookie=0. 150 */ 151 152struct ng_cmdlist { 153 u_int32_t cookie; /* command typecookie */ 154 int cmd; /* command number */ 155 const char *name; /* command name */ 156 const struct ng_parse_type *mesgType; /* args if !NGF_RESP */ 157 const struct ng_parse_type *respType; /* args if NGF_RESP */ 158}; 159 160/* 161 * Structure of a node type 162 * If data is sent to the "rcvdata()" entrypoint then the system 163 * may decide to defer it until later by queing it with the normal netgraph 164 * input queuing system. This is decidde by the HK_QUEUE flag being set in 165 * the flags word of the peer (receiving) hook. The dequeuing mechanism will 166 * ensure it is not requeued again. 167 * Note the input queueing system is to allow modules 168 * to 'release the stack' or to pass data across spl layers. 169 * The data will be redelivered as soon as the NETISR code runs 170 * which may be almost immediatly. A node may also do it's own queueing 171 * for other reasons (e.g. device output queuing). 172 */ 173struct ng_type { 174
|
201/* Send data packet with meta-data */ 202#define NG_SEND_DATA(err, hook, m, meta) \ 203 do { \ 204 (err) = ng_send_data((hook), (m), (meta), \ 205 NULL, NULL, NULL); \ 206 (m) = NULL; \ 207 (meta) = NULL; \ 208 } while (0) 209 210/* Send data packet with no meta-data */ 211#define NG_SEND_DATA_ONLY(err, hook, m) \ 212 do { \ 213 (err) = ng_send_data((hook), (m), NULL, \ 214 NULL, NULL, NULL); \ 215 (m) = NULL; \ 216 } while (0) 217 218/* Send data packet including a possible sync response pointer */ 219#define NG_SEND_DATA_RESP(err, hook, m, meta, rmsg) \ 220 do { \ 221 (err) = ng_send_data((hook), (m), (meta), \ 222 NULL, NULL, rmsg); \ 223 (m) = NULL; \ 224 (meta) = NULL; \ 225 } while (0) 226 227/* 228 * Send data packet including a possible sync response pointer 229 * Allow the callee to replace the data and pass it back 230 * or to simply 'reject it' or 'keep it' 231 */ 232#define NG_SEND_DATA_RET(err, hook, m, meta, rmsg) \ 233 do { \ 234 struct mbuf *rm = NULL; \ 235 meta_p rmeta = NULL; \ 236 (err) = ng_send_data((hook), (m), (meta), \ 237 &rm, &rmeta, (rmsg)); \ 238 (m) = rm; \ 239 (meta) = rmeta; \ 240 } while (0) 241 242 243/* Free metadata */ 244#define NG_FREE_META(meta) \ 245 do { \ 246 if ((meta)) { \ 247 FREE((meta), M_NETGRAPH); \ 248 meta = NULL; \ 249 } \ 250 } while (0) 251 252/* Free any data packet and/or meta-data */ 253#define NG_FREE_DATA(m, meta) \ 254 do { \ 255 if ((m)) { \ 256 m_freem((m)); \ 257 m = NULL; \ 258 } \ 259 NG_FREE_META((meta)); \ 260 } while (0) 261 262/* 263 * Use the NETGRAPH_INIT() macro to link a node type into the 264 * netgraph system. This works for types compiled into the kernel 265 * as well as KLD modules. The first argument should be the type 266 * name (eg, echo) and the second a pointer to the type struct. 267 * 268 * If a different link time is desired, e.g., a device driver that 269 * needs to install its netgraph type before probing, use the 270 * NETGRAPH_INIT_ORDERED() macro instead. Deivce drivers probably 271 * want to use SI_SUB_DRIVERS instead of SI_SUB_PSEUDO. 272 */ 273 274#define NETGRAPH_INIT_ORDERED(typename, typestructp, sub, order) \ 275static moduledata_t ng_##typename##_mod = { \ 276 "ng_" #typename, \ 277 ng_mod_event, \ 278 (typestructp) \ 279}; \ 280DECLARE_MODULE(ng_##typename, ng_##typename##_mod, sub, order); \ 281MODULE_DEPEND(ng_##typename, netgraph, 1, 1, 1) 282 283#define NETGRAPH_INIT(tn, tp) \ 284 NETGRAPH_INIT_ORDERED(tn, tp, SI_SUB_PSEUDO, SI_ORDER_ANY) 285 286/* Special malloc() type for netgraph structs and ctrl messages */ 287MALLOC_DECLARE(M_NETGRAPH); 288 289int ng_bypass(hook_p hook1, hook_p hook2); 290void ng_cutlinks(node_p node); 291int ng_con_nodes(node_p node, 292 const char *name, node_p node2, const char *name2); 293meta_p ng_copy_meta(meta_p meta); 294void ng_destroy_hook(hook_p hook); 295hook_p ng_findhook(node_p node, const char *name); 296node_p ng_findname(node_p node, const char *name); 297struct ng_type *ng_findtype(const char *type); 298int ng_make_node(const char *type, node_p *nodepp); 299int ng_make_node_common(struct ng_type *typep, node_p *nodep); 300int ng_mkpeer(node_p node, const char *name, const char *name2, char *type); 301int ng_mod_event(module_t mod, int what, void *arg); 302int ng_name_node(node_p node, const char *name); 303int ng_newtype(struct ng_type *tp); 304ng_ID_t ng_node2ID(node_p node); 305int ng_path2node(node_p here, const char *path, 306 node_p *dest, hook_p *lasthook); 307int ng_path_parse(char *addr, char **node, char **path, char **hook); 308int ng_queue_data(hook_p hook, struct mbuf *m, meta_p meta); 309int ng_queue_msg(node_p here, struct ng_mesg *msg, const char *address, 310 hook_p hook, char *retaddr); 311void ng_release_node(node_p node); 312void ng_rmnode(node_p node); 313int ng_send_data(hook_p hook, struct mbuf *m, meta_p meta, 314 struct mbuf **ret_m, meta_p *ret_meta, struct ng_mesg **resp); 315int ng_send_msg(node_p here, struct ng_mesg *msg, const char *address, 316 hook_p hook, char *retaddr, struct ng_mesg **resp); 317void ng_unname(node_p node); 318void ng_unref(node_p node); 319int ng_wait_node(node_p node, char *msg); 320 321#endif /* _NETGRAPH_NETGRAPH_H_ */ 322
|