| Commit | Line | Data |
|---|---|---|
| b06ebda0 MD |
1 | /* |
| 2 | * ng_message.h | |
| 3 | */ | |
| 4 | ||
| 5 | /*- | |
| 6 | * Copyright (c) 1996-1999 Whistle Communications, Inc. | |
| 7 | * All rights reserved. | |
| 8 | * | |
| 9 | * Subject to the following obligations and disclaimer of warranty, use and | |
| 10 | * redistribution of this software, in source or object code forms, with or | |
| 11 | * without modifications are expressly permitted by Whistle Communications; | |
| 12 | * provided, however, that: | |
| 13 | * 1. Any and all reproductions of the source or object code must include the | |
| 14 | * copyright notice above and the following disclaimer of warranties; and | |
| 15 | * 2. No rights are granted, in any manner or form, to use Whistle | |
| 16 | * Communications, Inc. trademarks, including the mark "WHISTLE | |
| 17 | * COMMUNICATIONS" on advertising, endorsements, or otherwise except as | |
| 18 | * such appears in the above copyright notice or in the software. | |
| 19 | * | |
| 20 | * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND | |
| 21 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO | |
| 22 | * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, | |
| 23 | * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF | |
| 24 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. | |
| 25 | * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY | |
| 26 | * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS | |
| 27 | * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. | |
| 28 | * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES | |
| 29 | * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING | |
| 30 | * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
| 31 | * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| 32 | * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY | |
| 33 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
| 35 | * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY | |
| 36 | * OF SUCH DAMAGE. | |
| 37 | * | |
| 38 | * Author: Julian Elischer <julian@freebsd.org> | |
| 39 | * | |
| 40 | * $FreeBSD: src/sys/netgraph/ng_message.h,v 1.29 2006/10/17 11:01:20 glebius Exp $ | |
| 5a975a3d | 41 | * $DragonFly: src/sys/netgraph7/ng_message.h,v 1.2 2008/06/26 23:05:35 dillon Exp $ |
| b06ebda0 MD |
42 | * $Whistle: ng_message.h,v 1.12 1999/01/25 01:17:44 archie Exp $ |
| 43 | */ | |
| 44 | ||
| 45 | #ifndef _NETGRAPH_NG_MESSAGE_H_ | |
| 46 | #define _NETGRAPH_NG_MESSAGE_H_ | |
| 47 | ||
| 99dd49c5 SW |
48 | #include <sys/ioccom.h> |
| 49 | ||
| b06ebda0 MD |
50 | /* ASCII string size limits */ |
| 51 | #define NG_TYPESIZ 32 /* max type name len (including null) */ | |
| 52 | #define NG_HOOKSIZ 32 /* max hook name len (including null) */ | |
| 53 | #define NG_NODESIZ 32 /* max node name len (including null) */ | |
| 54 | #define NG_PATHSIZ 512 /* max path len (including null) */ | |
| 55 | #define NG_CMDSTRSIZ 32 /* max command string (including null) */ | |
| 56 | ||
| 57 | #ifndef BURN_BRIDGES | |
| 58 | /* don't use these - they will go away */ | |
| 59 | #define NG_TYPELEN (NG_TYPESIZ - 1) | |
| 60 | #define NG_HOOKLEN (NG_HOOKSIZ - 1) | |
| 61 | #define NG_NODELEN (NG_NODESIZ - 1) | |
| 62 | #define NG_PATHLEN (NG_PATHSIZ - 1) | |
| 63 | #define NG_CMDSTRLEN (NG_CMDSTRSIZ - 1) | |
| 64 | #endif | |
| 65 | ||
| 66 | #define NG_TEXTRESPONSE 1024 /* allow this length for a text response */ | |
| 67 | ||
| 68 | /* A netgraph message */ | |
| 69 | struct ng_mesg { | |
| 70 | struct ng_msghdr { | |
| 71 | u_char version; /* == NGM_VERSION */ | |
| 72 | u_char spare; /* pad to 4 bytes */ | |
| 73 | u_int16_t spare2; | |
| 74 | u_int32_t arglen; /* length of data */ | |
| 75 | u_int32_t cmd; /* command identifier */ | |
| 76 | u_int32_t flags; /* message status */ | |
| 77 | u_int32_t token; /* match with reply */ | |
| 78 | u_int32_t typecookie; /* node's type cookie */ | |
| 79 | u_char cmdstr[NG_CMDSTRSIZ]; /* cmd string + \0 */ | |
| 80 | } header; | |
| 81 | char data[]; /* placeholder for actual data */ | |
| 82 | }; | |
| 83 | ||
| 84 | /* This command is guaranteed to not alter data (or'd into the command). */ | |
| 85 | #define NGM_READONLY 0x10000000 | |
| 86 | /* This command is guaranteed to have a reply (or'd into the command). */ | |
| 87 | #define NGM_HASREPLY 0x20000000 | |
| 88 | ||
| 89 | /* Keep this in sync with the above structure definition */ | |
| 90 | #define NG_GENERIC_NG_MESG_INFO(dtype) { \ | |
| 91 | { "version", &ng_parse_uint8_type }, \ | |
| 92 | { "spare", &ng_parse_uint8_type }, \ | |
| 93 | { "spare2", &ng_parse_uint16_type }, \ | |
| 94 | { "arglen", &ng_parse_uint32_type }, \ | |
| 95 | { "cmd", &ng_parse_uint32_type }, \ | |
| 96 | { "flags", &ng_parse_hint32_type }, \ | |
| 97 | { "token", &ng_parse_uint32_type }, \ | |
| 98 | { "typecookie", &ng_parse_uint32_type }, \ | |
| 99 | { "cmdstr", &ng_parse_cmdbuf_type }, \ | |
| 100 | { "data", (dtype) }, \ | |
| 101 | { NULL } \ | |
| 102 | } | |
| 103 | ||
| 104 | /* | |
| 105 | * Netgraph message header compatibility field | |
| 106 | * Interfaces within the kernel are defined by a different | |
| 107 | * value (see NG_ABI_VERSION in netgraph.h) | |
| 108 | */ | |
| 109 | #define NG_VERSION 8 | |
| 110 | ||
| 111 | /* Flags field flags */ | |
| 112 | #define NGF_ORIG 0x00000000 /* the msg is the original request */ | |
| 113 | #define NGF_RESP 0x00000001 /* the message is a response */ | |
| 114 | ||
| 115 | /* Type of a unique node ID. */ | |
| 116 | #define ng_ID_t uint32_t | |
| 117 | ||
| 118 | /* | |
| 119 | * Here we describe the "generic" messages that all nodes inherently | |
| 120 | * understand. With the exception of NGM_TEXT_STATUS, these are handled | |
| 121 | * automatically by the base netgraph code. | |
| 122 | */ | |
| 123 | ||
| 124 | /* Generic message type cookie */ | |
| 125 | #define NGM_GENERIC_COOKIE 1137070366 | |
| 126 | ||
| 127 | /* Generic messages defined for this type cookie. */ | |
| 128 | enum { | |
| 129 | NGM_SHUTDOWN = 1, /* Shut down node. */ | |
| 130 | NGM_MKPEER = 2, /* Create and attach a peer node. */ | |
| 131 | NGM_CONNECT = 3, /* Connect two nodes. */ | |
| 132 | NGM_NAME = 4, /* Give a node a name. */ | |
| 133 | NGM_RMHOOK = 5, /* Break a connection between two nodes. */ | |
| 134 | ||
| 135 | /* Get nodeinfo for target. */ | |
| 136 | NGM_NODEINFO = (6|NGM_READONLY|NGM_HASREPLY), | |
| 137 | /* Get list of hooks on node. */ | |
| 138 | NGM_LISTHOOKS = (7|NGM_READONLY|NGM_HASREPLY), | |
| 139 | /* List globally named nodes. */ | |
| 140 | NGM_LISTNAMES = (8|NGM_READONLY|NGM_HASREPLY), | |
| 141 | /* List all nodes. */ | |
| 142 | NGM_LISTNODES = (9|NGM_READONLY|NGM_HASREPLY), | |
| 143 | /* List installed node types. */ | |
| 144 | NGM_LISTTYPES = (10|NGM_READONLY|NGM_HASREPLY), | |
| 145 | /* (optional) Get text status. */ | |
| 146 | NGM_TEXT_STATUS = (11|NGM_READONLY|NGM_HASREPLY), | |
| 147 | /* Convert struct ng_mesg to ASCII. */ | |
| 148 | NGM_BINARY2ASCII= (12|NGM_READONLY|NGM_HASREPLY), | |
| 149 | /* Convert ASCII to struct ng_mesg. */ | |
| 150 | NGM_ASCII2BINARY= (13|NGM_READONLY|NGM_HASREPLY), | |
| 151 | /* (optional) Get/set text config. */ | |
| 152 | NGM_TEXT_CONFIG = 14, | |
| 153 | }; | |
| 154 | ||
| 155 | /* | |
| 156 | * Flow control and intra node control messages. | |
| 157 | * These are routed between nodes to allow flow control and to allow | |
| 158 | * events to be passed around the graph. | |
| 159 | * There will be some form of default handling for these but I | |
| 160 | * do not yet know what it is.. | |
| 161 | */ | |
| 162 | ||
| 163 | /* Generic message type cookie */ | |
| 164 | #define NGM_FLOW_COOKIE 851672669 /* temp for debugging */ | |
| 165 | ||
| 166 | /* Upstream messages */ | |
| 167 | #define NGM_LINK_IS_UP 32 /* e.g. carrier found - no data */ | |
| 168 | #define NGM_LINK_IS_DOWN 33 /* carrier lost, includes queue state */ | |
| 169 | #define NGM_HIGH_WATER_PASSED 34 /* includes queue state */ | |
| 170 | #define NGM_LOW_WATER_PASSED 35 /* includes queue state */ | |
| 171 | #define NGM_SYNC_QUEUE_STATE 36 /* sync response from sending packet */ | |
| 172 | ||
| 173 | /* Downstream messages */ | |
| 174 | #define NGM_DROP_LINK 41 /* drop DTR, etc. - stay in the graph */ | |
| 175 | #define NGM_RAISE_LINK 42 /* if you previously dropped it */ | |
| 176 | #define NGM_FLUSH_QUEUE 43 /* no data */ | |
| 177 | #define NGM_GET_BANDWIDTH (44|NGM_READONLY) /* either real or measured */ | |
| 178 | #define NGM_SET_XMIT_Q_LIMITS 45 /* includes queue state */ | |
| 179 | #define NGM_GET_XMIT_Q_LIMITS (46|NGM_READONLY) /* returns queue state */ | |
| 180 | #define NGM_MICROMANAGE 47 /* We want sync. queue state | |
| 181 | reply for each packet sent */ | |
| 182 | #define NGM_SET_FLOW_MANAGER 48 /* send flow control here */ | |
| 183 | /* Structure used for NGM_MKPEER */ | |
| 184 | struct ngm_mkpeer { | |
| 185 | char type[NG_TYPESIZ]; /* peer type */ | |
| 186 | char ourhook[NG_HOOKSIZ]; /* hook name */ | |
| 187 | char peerhook[NG_HOOKSIZ]; /* peer hook name */ | |
| 188 | }; | |
| 189 | ||
| 190 | /* Keep this in sync with the above structure definition */ | |
| 191 | #define NG_GENERIC_MKPEER_INFO() { \ | |
| 192 | { "type", &ng_parse_typebuf_type }, \ | |
| 193 | { "ourhook", &ng_parse_hookbuf_type }, \ | |
| 194 | { "peerhook", &ng_parse_hookbuf_type }, \ | |
| 195 | { NULL } \ | |
| 196 | } | |
| 197 | ||
| 198 | /* Structure used for NGM_CONNECT */ | |
| 199 | struct ngm_connect { | |
| 200 | char path[NG_PATHSIZ]; /* peer path */ | |
| 201 | char ourhook[NG_HOOKSIZ]; /* hook name */ | |
| 202 | char peerhook[NG_HOOKSIZ]; /* peer hook name */ | |
| 203 | }; | |
| 204 | ||
| 205 | /* Keep this in sync with the above structure definition */ | |
| 206 | #define NG_GENERIC_CONNECT_INFO() { \ | |
| 207 | { "path", &ng_parse_pathbuf_type }, \ | |
| 208 | { "ourhook", &ng_parse_hookbuf_type }, \ | |
| 209 | { "peerhook", &ng_parse_hookbuf_type }, \ | |
| 210 | { NULL } \ | |
| 211 | } | |
| 212 | ||
| 213 | /* Structure used for NGM_NAME */ | |
| 214 | struct ngm_name { | |
| 215 | char name[NG_NODESIZ]; /* node name */ | |
| 216 | }; | |
| 217 | ||
| 218 | /* Keep this in sync with the above structure definition */ | |
| 219 | #define NG_GENERIC_NAME_INFO() { \ | |
| 220 | { "name", &ng_parse_nodebuf_type }, \ | |
| 221 | { NULL } \ | |
| 222 | } | |
| 223 | ||
| 224 | /* Structure used for NGM_RMHOOK */ | |
| 225 | struct ngm_rmhook { | |
| 226 | char ourhook[NG_HOOKSIZ]; /* hook name */ | |
| 227 | }; | |
| 228 | ||
| 229 | /* Keep this in sync with the above structure definition */ | |
| 230 | #define NG_GENERIC_RMHOOK_INFO() { \ | |
| 231 | { "hook", &ng_parse_hookbuf_type }, \ | |
| 232 | { NULL } \ | |
| 233 | } | |
| 234 | ||
| 235 | /* Structure used for NGM_NODEINFO */ | |
| 236 | struct nodeinfo { | |
| 237 | char name[NG_NODESIZ]; /* node name (if any) */ | |
| 238 | char type[NG_TYPESIZ]; /* peer type */ | |
| 239 | ng_ID_t id; /* unique identifier */ | |
| 240 | u_int32_t hooks; /* number of active hooks */ | |
| 241 | }; | |
| 242 | ||
| 243 | /* Keep this in sync with the above structure definition */ | |
| 244 | #define NG_GENERIC_NODEINFO_INFO() { \ | |
| 245 | { "name", &ng_parse_nodebuf_type }, \ | |
| 246 | { "type", &ng_parse_typebuf_type }, \ | |
| 247 | { "id", &ng_parse_hint32_type }, \ | |
| 248 | { "hooks", &ng_parse_uint32_type }, \ | |
| 249 | { NULL } \ | |
| 250 | } | |
| 251 | ||
| 252 | /* Structure used for NGM_LISTHOOKS */ | |
| 253 | struct linkinfo { | |
| 254 | char ourhook[NG_HOOKSIZ]; /* hook name */ | |
| 255 | char peerhook[NG_HOOKSIZ]; /* peer hook */ | |
| 256 | struct nodeinfo nodeinfo; | |
| 257 | }; | |
| 258 | ||
| 259 | /* Keep this in sync with the above structure definition */ | |
| 260 | #define NG_GENERIC_LINKINFO_INFO(nitype) { \ | |
| 261 | { "ourhook", &ng_parse_hookbuf_type }, \ | |
| 262 | { "peerhook", &ng_parse_hookbuf_type }, \ | |
| 263 | { "nodeinfo", (nitype) }, \ | |
| 264 | { NULL } \ | |
| 265 | } | |
| 266 | ||
| 267 | struct hooklist { | |
| 268 | struct nodeinfo nodeinfo; /* node information */ | |
| 269 | struct linkinfo link[]; /* info about each hook */ | |
| 270 | }; | |
| 271 | ||
| 272 | /* Keep this in sync with the above structure definition */ | |
| 273 | #define NG_GENERIC_HOOKLIST_INFO(nitype,litype) { \ | |
| 274 | { "nodeinfo", (nitype) }, \ | |
| 275 | { "linkinfo", (litype) }, \ | |
| 276 | { NULL } \ | |
| 277 | } | |
| 278 | ||
| 279 | /* Structure used for NGM_LISTNAMES/NGM_LISTNODES */ | |
| 280 | struct namelist { | |
| 281 | u_int32_t numnames; | |
| 282 | struct nodeinfo nodeinfo[]; | |
| 283 | }; | |
| 284 | ||
| 285 | /* Keep this in sync with the above structure definition */ | |
| 286 | #define NG_GENERIC_LISTNODES_INFO(niarraytype) { \ | |
| 287 | { "numnames", &ng_parse_uint32_type }, \ | |
| 288 | { "nodeinfo", (niarraytype) }, \ | |
| 289 | { NULL } \ | |
| 290 | } | |
| 291 | ||
| 292 | /* Structure used for NGM_LISTTYPES */ | |
| 293 | struct typeinfo { | |
| 294 | char type_name[NG_TYPESIZ]; /* name of type */ | |
| 295 | u_int32_t numnodes; /* number alive */ | |
| 296 | }; | |
| 297 | ||
| 298 | /* Keep this in sync with the above structure definition */ | |
| 299 | #define NG_GENERIC_TYPEINFO_INFO() { \ | |
| 300 | { "typename", &ng_parse_typebuf_type }, \ | |
| 301 | { "numnodes", &ng_parse_uint32_type }, \ | |
| 302 | { NULL } \ | |
| 303 | } | |
| 304 | ||
| 305 | struct typelist { | |
| 306 | u_int32_t numtypes; | |
| 307 | struct typeinfo typeinfo[]; | |
| 308 | }; | |
| 309 | ||
| 310 | /* Keep this in sync with the above structure definition */ | |
| 311 | #define NG_GENERIC_TYPELIST_INFO(tiarraytype) { \ | |
| 312 | { "numtypes", &ng_parse_uint32_type }, \ | |
| 313 | { "typeinfo", (tiarraytype) }, \ | |
| 314 | { NULL } \ | |
| 315 | } | |
| 316 | ||
| 317 | struct ngm_bandwidth { | |
| 318 | u_int64_t nominal_in; | |
| 319 | u_int64_t seen_in; | |
| 320 | u_int64_t nominal_out; | |
| 321 | u_int64_t seen_out; | |
| 322 | }; | |
| 323 | ||
| 324 | /* Keep this in sync with the above structure definition */ | |
| 325 | #define NG_GENERIC_BANDWIDTH_INFO() { \ | |
| 326 | { "nominal_in", &ng_parse_uint64_type }, \ | |
| 327 | { "seen_in", &ng_parse_uint64_type }, \ | |
| 328 | { "nominal_out", &ng_parse_uint64_type }, \ | |
| 329 | { "seen_out", &ng_parse_uint64_type }, \ | |
| 330 | { NULL } \ | |
| 331 | } | |
| 332 | ||
| 333 | /* | |
| 334 | * Information about a node's 'output' queue. | |
| 335 | * This is NOT the netgraph input queueing mechanism, | |
| 336 | * but rather any queue the node may implement internally | |
| 337 | * This has to consider ALTQ if we are to work with it. | |
| 338 | * As far as I can see, ALTQ counts PACKETS, not bytes. | |
| 339 | * If ALTQ has several queues and one has passed a watermark | |
| 340 | * we should have the priority of that queue be real (and not -1) | |
| 341 | * XXX ALTQ stuff is just an idea..... | |
| 342 | */ | |
| 343 | struct ngm_queue_state { | |
| 344 | u_int queue_priority; /* maybe only low-pri is full. -1 = all*/ | |
| 345 | u_int max_queuelen_bytes; | |
| 346 | u_int max_queuelen_packets; | |
| 347 | u_int low_watermark; | |
| 348 | u_int high_watermark; | |
| 349 | u_int current; | |
| 350 | }; | |
| 351 | ||
| 352 | /* Keep this in sync with the above structure definition */ | |
| 353 | #define NG_GENERIC_QUEUE_INFO() { \ | |
| 354 | { "max_queuelen_bytes", &ng_parse_uint_type }, \ | |
| 355 | { "max_queuelen_packets", &ng_parse_uint_type }, \ | |
| 356 | { "high_watermark", &ng_parse_uint_type }, \ | |
| 357 | { "low_watermark", &ng_parse_uint_type }, \ | |
| 358 | { "current", &ng_parse_uint_type }, \ | |
| 359 | { NULL } \ | |
| 360 | } | |
| 361 | ||
| 362 | /* Tell a node who to send async flow control info to. */ | |
| 363 | struct flow_manager { | |
| 364 | ng_ID_t id; /* unique identifier */ | |
| 365 | }; | |
| 366 | ||
| 367 | /* Keep this in sync with the above structure definition */ | |
| 368 | #define NG_GENERIC_FLOW_MANAGER_INFO() { \ | |
| 369 | { "id", &ng_parse_hint32_type }, \ | |
| 370 | { NULL } \ | |
| 371 | } | |
| 372 | ||
| 373 | ||
| 374 | /* | |
| 375 | * For netgraph nodes that are somehow associated with file descriptors | |
| 376 | * (e.g., a device that has a /dev entry and is also a netgraph node), | |
| 377 | * we define a generic ioctl for requesting the corresponding nodeinfo | |
| 378 | * structure and for assigning a name (if there isn't one already). | |
| b06ebda0 MD |
379 | */ |
| 380 | ||
| 381 | #define NGIOCGINFO _IOR('N', 40, struct nodeinfo) /* get node info */ | |
| 382 | #define NGIOCSETNAME _IOW('N', 41, struct ngm_name) /* set node name */ | |
| 383 | ||
| 384 | #ifdef _KERNEL | |
| 385 | /* | |
| 386 | * Allocate and initialize a netgraph message "msg" with "len" | |
| 387 | * extra bytes of argument. Sets "msg" to NULL if fails. | |
| 388 | * Does not initialize token. | |
| 389 | */ | |
| 390 | #define NG_MKMESSAGE(msg, cookie, cmdid, len, how) \ | |
| 391 | do { \ | |
| fc025606 SW |
392 | (msg) = kmalloc(sizeof(struct ng_mesg) + (len), \ |
| 393 | M_NETGRAPH_MSG, (how) | M_ZERO); \ | |
| b06ebda0 MD |
394 | if ((msg) == NULL) \ |
| 395 | break; \ | |
| 396 | (msg)->header.version = NG_VERSION; \ | |
| 397 | (msg)->header.typecookie = (cookie); \ | |
| 398 | (msg)->header.cmd = (cmdid); \ | |
| 399 | (msg)->header.arglen = (len); \ | |
| 400 | strncpy((msg)->header.cmdstr, #cmdid, \ | |
| 401 | sizeof((msg)->header.cmdstr) - 1); \ | |
| 402 | } while (0) | |
| 403 | ||
| 404 | /* | |
| 405 | * Allocate and initialize a response "rsp" to a message "msg" | |
| 406 | * with "len" extra bytes of argument. Sets "rsp" to NULL if fails. | |
| 407 | */ | |
| 408 | #define NG_MKRESPONSE(rsp, msg, len, how) \ | |
| 409 | do { \ | |
| fc025606 SW |
410 | (rsp) = kmalloc(sizeof(struct ng_mesg) + (len), \ |
| 411 | M_NETGRAPH_MSG, (how) | M_ZERO); \ | |
| b06ebda0 MD |
412 | if ((rsp) == NULL) \ |
| 413 | break; \ | |
| 414 | (rsp)->header.version = NG_VERSION; \ | |
| 415 | (rsp)->header.arglen = (len); \ | |
| 416 | (rsp)->header.token = (msg)->header.token; \ | |
| 417 | (rsp)->header.typecookie = (msg)->header.typecookie; \ | |
| 418 | (rsp)->header.cmd = (msg)->header.cmd; \ | |
| 419 | bcopy((msg)->header.cmdstr, (rsp)->header.cmdstr, \ | |
| 420 | sizeof((rsp)->header.cmdstr)); \ | |
| 421 | (rsp)->header.flags |= NGF_RESP; \ | |
| 422 | } while (0) | |
| 423 | ||
| 424 | /* | |
| 425 | * Make a copy of message. Sets "copy" to NULL if fails. | |
| 426 | */ | |
| 427 | #define NG_COPYMESSAGE(copy, msg, how) \ | |
| 428 | do { \ | |
| fc025606 SW |
429 | (copy) = kmalloc(sizeof(struct ng_mesg) + (msg)->header.arglen,\ |
| 430 | M_NETGRAPH_MSG, (how) | M_ZERO); \ | |
| b06ebda0 MD |
431 | if ((copy) == NULL) \ |
| 432 | break; \ | |
| 433 | (copy)->header.version = NG_VERSION; \ | |
| 434 | (copy)->header.arglen = (msg)->header.arglen; \ | |
| 435 | (copy)->header.token = (msg)->header.token; \ | |
| 436 | (copy)->header.typecookie = (msg)->header.typecookie; \ | |
| 437 | (copy)->header.cmd = (msg)->header.cmd; \ | |
| 438 | (copy)->header.flags = (msg)->header.flags; \ | |
| 439 | bcopy((msg)->header.cmdstr, (copy)->header.cmdstr, \ | |
| 440 | sizeof((copy)->header.cmdstr)); \ | |
| 441 | if ((msg)->header.arglen > 0) \ | |
| 442 | bcopy((msg)->data, (copy)->data, (msg)->header.arglen); \ | |
| 443 | } while (0) | |
| 444 | ||
| 445 | #endif /* _KERNEL */ | |
| 446 | ||
| 447 | #endif /* _NETGRAPH_NG_MESSAGE_H_ */ |