FreeBSD kernel netgraph code
ng_patch.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2010 Maxim Ignatenko <gelraen.ua@gmail.com>
5 * Copyright (c) 2015 Dmitry Vagin <daemon.hammer@ya.ru>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD$");
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/endian.h>
38#include <sys/malloc.h>
39#include <sys/mbuf.h>
40
41#include <net/bpf.h>
42#include <net/ethernet.h>
43
44#include <netgraph/ng_message.h>
45#include <netgraph/ng_parse.h>
46#include <netgraph/netgraph.h>
47
48#include <netgraph/ng_patch.h>
49
50/* private data */
54 uint8_t dlt; /* DLT_XXX from bpf.h */
57};
58
59typedef struct ng_patch_priv *priv_p;
60
61/* Netgraph methods */
68#define ERROUT(x) { error = (x); goto done; }
69
70static int
72 const u_char *start, const u_char *buf)
73{
74 const struct ng_patch_config *conf;
75
76 conf = (const struct ng_patch_config *)(buf -
77 offsetof(struct ng_patch_config, ops));
78
79 return (conf->count);
80}
81
84static const struct ng_parse_type ng_patch_op_type = {
87};
88
92};
96};
97
100static const struct ng_parse_type ng_patch_config_type = {
103};
104
107static const struct ng_parse_type ng_patch_stats_type = {
110};
111
112static const struct ng_cmdlist ng_patch_cmdlist[] = {
113 {
116 "getdlt",
117 NULL,
119 },
120 {
123 "setdlt",
125 NULL
126 },
127 {
130 "getconfig",
131 NULL,
133 },
134 {
137 "setconfig",
139 NULL
140 },
141 {
144 "getstats",
145 NULL,
147 },
148 {
151 "clrstats",
152 NULL,
153 NULL
154 },
155 {
158 "getclrstats",
159 NULL,
161 },
162 { 0 }
163};
164
165static struct ng_type typestruct = {
167 .name = NG_PATCH_NODE_TYPE,
168 .constructor = ng_patch_constructor,
169 .rcvmsg = ng_patch_rcvmsg,
170 .shutdown = ng_patch_shutdown,
171 .newhook = ng_patch_newhook,
172 .rcvdata = ng_patch_rcvdata,
173 .disconnect = ng_patch_disconnect,
174 .cmdlist = ng_patch_cmdlist,
175};
176
178
179static int
181{
183
184 privdata = malloc(sizeof(*privdata), M_NETGRAPH, M_WAITOK | M_ZERO);
185 privdata->dlt = DLT_RAW;
186
188
189 return (0);
190}
191
192static int
193ng_patch_newhook(node_p node, hook_p hook, const char *name)
194{
195 const priv_p privp = NG_NODE_PRIVATE(node);
196
197 if (strncmp(name, NG_PATCH_HOOK_IN, strlen(NG_PATCH_HOOK_IN)) == 0) {
198 privp->in = hook;
199 } else if (strncmp(name, NG_PATCH_HOOK_OUT,
200 strlen(NG_PATCH_HOOK_OUT)) == 0) {
201 privp->out = hook;
202 } else
203 return (EINVAL);
204
205 return (0);
206}
207
208static int
209ng_patch_rcvmsg(node_p node, item_p item, hook_p lasthook)
210{
211 const priv_p privp = NG_NODE_PRIVATE(node);
212 struct ng_patch_config *conf, *newconf;
213 struct ng_mesg *msg;
214 struct ng_mesg *resp = NULL;
215 int i, error = 0;
216
217 NGI_GET_MSG(item, msg);
218
220 ERROUT(EINVAL);
221
222 switch (msg->header.cmd)
223 {
225 if (privp->conf == NULL)
226 ERROUT(0);
227
228 NG_MKRESPONSE(resp, msg,
229 NG_PATCH_CONF_SIZE(privp->conf->count), M_WAITOK);
230
231 if (resp == NULL)
232 ERROUT(ENOMEM);
233
234 bcopy(privp->conf, resp->data,
235 NG_PATCH_CONF_SIZE(privp->conf->count));
236
237 conf = (struct ng_patch_config *) resp->data;
238
239 for (i = 0; i < conf->count; i++) {
240 switch (conf->ops[i].length)
241 {
242 case 1:
243 conf->ops[i].val.v8 = conf->ops[i].val.v1;
244 break;
245 case 2:
246 conf->ops[i].val.v8 = conf->ops[i].val.v2;
247 break;
248 case 4:
249 conf->ops[i].val.v8 = conf->ops[i].val.v4;
250 break;
251 case 8:
252 break;
253 }
254 }
255
256 break;
257
259 conf = (struct ng_patch_config *) msg->data;
260
261 if (msg->header.arglen < sizeof(struct ng_patch_config) ||
263 ERROUT(EINVAL);
264
265 for (i = 0; i < conf->count; i++) {
266 switch (conf->ops[i].length)
267 {
268 case 1:
269 conf->ops[i].val.v1 = (uint8_t) conf->ops[i].val.v8;
270 break;
271 case 2:
272 conf->ops[i].val.v2 = (uint16_t) conf->ops[i].val.v8;
273 break;
274 case 4:
275 conf->ops[i].val.v4 = (uint32_t) conf->ops[i].val.v8;
276 break;
277 case 8:
278 break;
279 default:
280 ERROUT(EINVAL);
281 }
282 }
283
285 conf->relative_offset = !!conf->relative_offset;
286
287 newconf = malloc(NG_PATCH_CONF_SIZE(conf->count), M_NETGRAPH, M_WAITOK | M_ZERO);
288
289 bcopy(conf, newconf, NG_PATCH_CONF_SIZE(conf->count));
290
291 if (privp->conf)
292 free(privp->conf, M_NETGRAPH);
293
294 privp->conf = newconf;
295
296 break;
297
301 if (msg->header.cmd != NGM_PATCH_CLR_STATS) {
302 NG_MKRESPONSE(resp, msg, sizeof(struct ng_patch_stats), M_WAITOK);
303
304 if (resp == NULL)
305 ERROUT(ENOMEM);
306
307 bcopy(&(privp->stats), resp->data, sizeof(struct ng_patch_stats));
308 }
309
310 if (msg->header.cmd != NGM_PATCH_GET_STATS)
311 bzero(&(privp->stats), sizeof(struct ng_patch_stats));
312
313 break;
314
315 case NGM_PATCH_GETDLT:
316 NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK);
317
318 if (resp == NULL)
319 ERROUT(ENOMEM);
320
321 *((uint8_t *) resp->data) = privp->dlt;
322
323 break;
324
325 case NGM_PATCH_SETDLT:
326 if (msg->header.arglen != sizeof(uint8_t))
327 ERROUT(EINVAL);
328
329 switch (*(uint8_t *) msg->data)
330 {
331 case DLT_EN10MB:
332 case DLT_RAW:
333 privp->dlt = *(uint8_t *) msg->data;
334 break;
335
336 default:
337 ERROUT(EINVAL);
338 }
339
340 break;
341
342 default:
343 ERROUT(EINVAL);
344 }
345
346done:
347 NG_RESPOND_MSG(error, node, item, resp);
348 NG_FREE_MSG(msg);
349
350 return (error);
351}
352
353static void
354do_patch(priv_p privp, struct mbuf *m, int global_offset)
355{
356 int i, offset, patched = 0;
357 union ng_patch_op_val val;
358
359 for (i = 0; i < privp->conf->count; i++) {
360 offset = global_offset + privp->conf->ops[i].offset;
361
362 if (offset + privp->conf->ops[i].length > m->m_pkthdr.len)
363 continue;
364
365 /* for "=" operation we don't need to copy data from mbuf */
366 if (privp->conf->ops[i].mode != NG_PATCH_MODE_SET)
367 m_copydata(m, offset, privp->conf->ops[i].length, (caddr_t) &val);
368
369 switch (privp->conf->ops[i].length)
370 {
371 case 1:
372 switch (privp->conf->ops[i].mode)
373 {
375 val.v1 = privp->conf->ops[i].val.v1;
376 break;
378 val.v1 += privp->conf->ops[i].val.v1;
379 break;
381 val.v1 -= privp->conf->ops[i].val.v1;
382 break;
384 val.v1 *= privp->conf->ops[i].val.v1;
385 break;
387 val.v1 /= privp->conf->ops[i].val.v1;
388 break;
390 *((int8_t *) &val) = - *((int8_t *) &val);
391 break;
393 val.v1 &= privp->conf->ops[i].val.v1;
394 break;
395 case NG_PATCH_MODE_OR:
396 val.v1 |= privp->conf->ops[i].val.v1;
397 break;
399 val.v1 ^= privp->conf->ops[i].val.v1;
400 break;
402 val.v1 <<= privp->conf->ops[i].val.v1;
403 break;
405 val.v1 >>= privp->conf->ops[i].val.v1;
406 break;
407 }
408 break;
409
410 case 2:
411 val.v2 = ntohs(val.v2);
412
413 switch (privp->conf->ops[i].mode)
414 {
416 val.v2 = privp->conf->ops[i].val.v2;
417 break;
419 val.v2 += privp->conf->ops[i].val.v2;
420 break;
422 val.v2 -= privp->conf->ops[i].val.v2;
423 break;
425 val.v2 *= privp->conf->ops[i].val.v2;
426 break;
428 val.v2 /= privp->conf->ops[i].val.v2;
429 break;
431 *((int16_t *) &val) = - *((int16_t *) &val);
432 break;
434 val.v2 &= privp->conf->ops[i].val.v2;
435 break;
436 case NG_PATCH_MODE_OR:
437 val.v2 |= privp->conf->ops[i].val.v2;
438 break;
440 val.v2 ^= privp->conf->ops[i].val.v2;
441 break;
443 val.v2 <<= privp->conf->ops[i].val.v2;
444 break;
446 val.v2 >>= privp->conf->ops[i].val.v2;
447 break;
448 }
449
450 val.v2 = htons(val.v2);
451
452 break;
453
454 case 4:
455 val.v4 = ntohl(val.v4);
456
457 switch (privp->conf->ops[i].mode)
458 {
460 val.v4 = privp->conf->ops[i].val.v4;
461 break;
463 val.v4 += privp->conf->ops[i].val.v4;
464 break;
466 val.v4 -= privp->conf->ops[i].val.v4;
467 break;
469 val.v4 *= privp->conf->ops[i].val.v4;
470 break;
472 val.v4 /= privp->conf->ops[i].val.v4;
473 break;
475 *((int32_t *) &val) = - *((int32_t *) &val);
476 break;
478 val.v4 &= privp->conf->ops[i].val.v4;
479 break;
480 case NG_PATCH_MODE_OR:
481 val.v4 |= privp->conf->ops[i].val.v4;
482 break;
484 val.v4 ^= privp->conf->ops[i].val.v4;
485 break;
487 val.v4 <<= privp->conf->ops[i].val.v4;
488 break;
490 val.v4 >>= privp->conf->ops[i].val.v4;
491 break;
492 }
493
494 val.v4 = htonl(val.v4);
495
496 break;
497
498 case 8:
499 val.v8 = be64toh(val.v8);
500
501 switch (privp->conf->ops[i].mode)
502 {
504 val.v8 = privp->conf->ops[i].val.v8;
505 break;
507 val.v8 += privp->conf->ops[i].val.v8;
508 break;
510 val.v8 -= privp->conf->ops[i].val.v8;
511 break;
513 val.v8 *= privp->conf->ops[i].val.v8;
514 break;
516 val.v8 /= privp->conf->ops[i].val.v8;
517 break;
519 *((int64_t *) &val) = - *((int64_t *) &val);
520 break;
522 val.v8 &= privp->conf->ops[i].val.v8;
523 break;
524 case NG_PATCH_MODE_OR:
525 val.v8 |= privp->conf->ops[i].val.v8;
526 break;
528 val.v8 ^= privp->conf->ops[i].val.v8;
529 break;
531 val.v8 <<= privp->conf->ops[i].val.v8;
532 break;
534 val.v8 >>= privp->conf->ops[i].val.v8;
535 break;
536 }
537
538 val.v8 = htobe64(val.v8);
539
540 break;
541 }
542
543 m_copyback(m, offset, privp->conf->ops[i].length, (caddr_t) &val);
544 patched = 1;
545 }
546
547 if (patched)
548 privp->stats.patched++;
549}
550
551static int
553{
555 struct mbuf *m;
556 hook_p out;
557 int pullup_len = 0;
558 int error = 0;
559
560 priv->stats.received++;
561
562 NGI_GET_M(item, m);
563
564#define PULLUP_CHECK(mbuf, length) do { \
565 pullup_len += length; \
566 if (((mbuf)->m_pkthdr.len < pullup_len) || \
567 (pullup_len > MHLEN)) { \
568 error = EINVAL; \
569 goto bypass; \
570 } \
571 if ((mbuf)->m_len < pullup_len && \
572 (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \
573 error = ENOBUFS; \
574 goto drop; \
575 } \
576} while (0)
577
578 if (priv->conf && hook == priv->in &&
579 m && (m->m_flags & M_PKTHDR)) {
580 m = m_unshare(m, M_NOWAIT);
581
582 if (m == NULL)
583 ERROUT(ENOMEM);
584
585 if (priv->conf->relative_offset) {
586 struct ether_header *eh;
587 struct ng_patch_vlan_header *vh;
588 uint16_t etype;
589
590 switch (priv->dlt)
591 {
592 case DLT_EN10MB:
593 PULLUP_CHECK(m, sizeof(struct ether_header));
594 eh = mtod(m, struct ether_header *);
595 etype = ntohs(eh->ether_type);
596
597 for (;;) { /* QinQ support */
598 switch (etype)
599 {
600 case 0x8100:
601 case 0x88A8:
602 case 0x9100:
603 PULLUP_CHECK(m, sizeof(struct ng_patch_vlan_header));
604 vh = (struct ng_patch_vlan_header *) mtodo(m,
605 pullup_len - sizeof(struct ng_patch_vlan_header));
606 etype = ntohs(vh->etype);
607 break;
608
609 default:
610 goto loopend;
611 }
612 }
613loopend:
614 break;
615
616 case DLT_RAW:
617 break;
618
619 default:
620 ERROUT(EINVAL);
621 }
622 }
623
624 do_patch(priv, m, pullup_len);
625
626 m->m_pkthdr.csum_flags |= priv->conf->csum_flags;
627 }
628
629#undef PULLUP_CHECK
630
631bypass:
632 out = NULL;
633
634 if (hook == priv->in) {
635 /* return frames on 'in' hook if 'out' not connected */
636 out = priv->out ? priv->out : priv->in;
637 } else if (hook == priv->out && priv->in) {
638 /* pass frames on 'out' hook if 'in' connected */
639 out = priv->in;
640 }
641
642 if (out == NULL)
643 ERROUT(0);
644
645 NG_FWD_NEW_DATA(error, item, out, m);
646
647 return (error);
648
649done:
650drop:
651 NG_FREE_ITEM(item);
652 NG_FREE_M(m);
653
654 priv->stats.dropped++;
655
656 return (error);
657}
658
659static int
661{
662 const priv_p privdata = NG_NODE_PRIVATE(node);
663
664 NG_NODE_SET_PRIVATE(node, NULL);
665 NG_NODE_UNREF(node);
666
667 if (privdata->conf != NULL)
668 free(privdata->conf, M_NETGRAPH);
669
670 free(privdata, M_NETGRAPH);
671
672 return (0);
673}
674
675static int
677{
678 priv_p priv;
679
681
682 if (hook == priv->in) {
683 priv->in = NULL;
684 }
685
686 if (hook == priv->out) {
687 priv->out = NULL;
688 }
689
690 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
691 NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */
693
694 return (0);
695}
#define NG_HOOK_NODE(hook)
Definition: netgraph.h:339
#define NG_FREE_M(m)
Definition: netgraph.h:946
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
Definition: netgraph.h:105
int ng_disconnect_t(hook_p hook)
Definition: netgraph.h:107
#define NG_NODE_SET_PRIVATE(node, val)
Definition: netgraph.h:608
#define NG_RESPOND_MSG(error, here, item, resp)
Definition: netgraph.h:1025
#define NG_NODE_IS_VALID(node)
Definition: netgraph.h:610
#define NG_NODE_UNREF(node)
Definition: netgraph.h:607
int ng_rmnode_self(node_p here)
Definition: ng_base.c:1609
#define NG_FWD_NEW_DATA(error, item, hook, m)
Definition: netgraph.h:914
int ng_rcvdata_t(hook_p hook, item_p item)
Definition: netgraph.h:106
int ng_shutdown_t(node_p node)
Definition: netgraph.h:101
#define NG_FREE_ITEM(item)
Definition: netgraph.h:847
int ng_constructor_t(node_p node)
Definition: netgraph.h:99
#define NGI_GET_M(i, m)
Definition: netgraph.h:852
#define NG_FREE_MSG(msg)
Definition: netgraph.h:938
#define NG_ABI_VERSION
Definition: netgraph.h:77
#define NG_NODE_NUMHOOKS(node)
Definition: netgraph.h:615
#define NGI_GET_MSG(i, m)
Definition: netgraph.h:858
#define NG_NODE_PRIVATE(node)
Definition: netgraph.h:609
int ng_newhook_t(node_p node, hook_p hook, const char *name)
Definition: netgraph.h:102
u_int8_t type
#define NG_MKRESPONSE(rsp, msg, len, how)
Definition: ng_message.h:396
const struct ng_parse_type ng_parse_array_type
Definition: ng_parse.c:318
const struct ng_parse_type ng_parse_struct_type
Definition: ng_parse.c:222
const struct ng_parse_type ng_parse_uint8_type
Definition: ng_parse.c:413
static ng_newhook_t ng_patch_newhook
Definition: ng_patch.c:65
static const struct ng_parse_struct_field ng_patch_op_type_fields[]
Definition: ng_patch.c:83
static void do_patch(priv_p privp, struct mbuf *m, int global_offset)
Definition: ng_patch.c:354
static int ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, const u_char *buf)
Definition: ng_patch.c:71
#define ERROUT(x)
Definition: ng_patch.c:68
static ng_rcvdata_t ng_patch_rcvdata
Definition: ng_patch.c:66
static ng_shutdown_t ng_patch_shutdown
Definition: ng_patch.c:64
static const struct ng_parse_type ng_patch_op_type
Definition: ng_patch.c:84
static struct ng_type typestruct
Definition: ng_patch.c:165
#define PULLUP_CHECK(mbuf, length)
__FBSDID("$FreeBSD$")
static ng_constructor_t ng_patch_constructor
Definition: ng_patch.c:62
static const struct ng_parse_struct_field ng_patch_stats_fields[]
Definition: ng_patch.c:106
NETGRAPH_INIT(patch, &typestruct)
static const struct ng_parse_struct_field ng_patch_config_type_fields[]
Definition: ng_patch.c:99
static const struct ng_parse_type ng_patch_ops_array_type
Definition: ng_patch.c:93
static const struct ng_parse_array_info ng_patch_ops_array_info
Definition: ng_patch.c:89
static ng_disconnect_t ng_patch_disconnect
Definition: ng_patch.c:67
static const struct ng_cmdlist ng_patch_cmdlist[]
Definition: ng_patch.c:112
static const struct ng_parse_type ng_patch_stats_type
Definition: ng_patch.c:107
static ng_rcvmsg_t ng_patch_rcvmsg
Definition: ng_patch.c:63
struct ng_patch_priv * priv_p
Definition: ng_patch.c:59
static const struct ng_parse_type ng_patch_config_type
Definition: ng_patch.c:100
#define NG_PATCH_OP_TYPE
Definition: ng_patch.h:85
#define NG_PATCH_CONF_SIZE(count)
Definition: ng_patch.h:132
#define NG_PATCH_CSUM_IPV4
Definition: ng_patch.h:46
#define NG_PATCH_STATS_TYPE
Definition: ng_patch.h:93
#define NG_PATCH_CSUM_IPV6
Definition: ng_patch.h:47
#define NG_PATCH_CONFIG_TYPE
Definition: ng_patch.h:77
@ NGM_PATCH_SETCONFIG
Definition: ng_patch.h:51
@ NGM_PATCH_GET_STATS
Definition: ng_patch.h:53
@ NGM_PATCH_SETDLT
Definition: ng_patch.h:57
@ NGM_PATCH_GETDLT
Definition: ng_patch.h:56
@ NGM_PATCH_GETCLR_STATS
Definition: ng_patch.h:55
@ NGM_PATCH_GETCONFIG
Definition: ng_patch.h:52
@ NGM_PATCH_CLR_STATS
Definition: ng_patch.h:54
#define NG_PATCH_HOOK_OUT
Definition: ng_patch.h:43
#define NGM_PATCH_COOKIE
Definition: ng_patch.h:39
#define NG_PATCH_HOOK_IN
Definition: ng_patch.h:42
#define NG_PATCH_NODE_TYPE
Definition: ng_patch.h:36
@ NG_PATCH_MODE_DIV
Definition: ng_patch.h:66
@ NG_PATCH_MODE_AND
Definition: ng_patch.h:68
@ NG_PATCH_MODE_NEG
Definition: ng_patch.h:67
@ NG_PATCH_MODE_XOR
Definition: ng_patch.h:70
@ NG_PATCH_MODE_SET
Definition: ng_patch.h:62
@ NG_PATCH_MODE_OR
Definition: ng_patch.h:69
@ NG_PATCH_MODE_MUL
Definition: ng_patch.h:65
@ NG_PATCH_MODE_ADD
Definition: ng_patch.h:63
@ NG_PATCH_MODE_SHR
Definition: ng_patch.h:72
@ NG_PATCH_MODE_SHL
Definition: ng_patch.h:71
@ NG_PATCH_MODE_SUB
Definition: ng_patch.h:64
char *const name
Definition: ng_ppp.c:261
u_int32_t arglen
Definition: ng_message.h:62
u_int32_t typecookie
Definition: ng_message.h:66
struct ng_mesg::ng_msghdr header
char data[]
Definition: ng_message.h:69
uint64_t csum_flags
Definition: ng_patch.h:116
struct ng_patch_op ops[]
Definition: ng_patch.h:118
uint32_t count
Definition: ng_patch.h:115
uint32_t relative_offset
Definition: ng_patch.h:117
uint16_t length
Definition: ng_patch.h:109
union ng_patch_op_val val
Definition: ng_patch.h:111
struct ng_patch_config * conf
Definition: ng_patch.c:56
hook_p out
Definition: ng_patch.c:53
uint8_t dlt
Definition: ng_patch.c:54
hook_p in
Definition: ng_patch.c:52
u_int32_t version
Definition: netgraph.h:1077
Definition: ng_sscfu.c:66
struct stats stats
Definition: ng_sscop.c:98
Definition: ng_sscop.c:74
uint32_t v4
Definition: ng_patch.h:103
uint8_t v1
Definition: ng_patch.h:101
uint64_t v8
Definition: ng_patch.h:104
uint16_t v2
Definition: ng_patch.h:102