FreeBSD kernel netgraph code
ng_checksum.c
Go to the documentation of this file.
1/*-
2 * Copyright (c) 2015 Dmitry Vagin <daemon.hammer@ya.ru>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD$");
30
31#include "opt_inet.h"
32#include "opt_inet6.h"
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#include <sys/socket.h>
41
42#include <net/bpf.h>
43#include <net/ethernet.h>
44#include <net/if.h>
45#include <net/if_vlan_var.h>
46
47#include <netinet/in.h>
48#include <netinet/ip.h>
49#include <netinet/ip6.h>
50#include <netinet/tcp.h>
51#include <netinet/udp.h>
52#include <machine/in_cksum.h>
53
54#include <netgraph/ng_message.h>
55#include <netgraph/ng_parse.h>
56#include <netgraph/netgraph.h>
57
59
60/* private data */
64 uint8_t dlt; /* DLT_XXX from bpf.h */
67};
68
69typedef struct ng_checksum_priv *priv_p;
70
71/* Netgraph methods */
78#define ERROUT(x) { error = (x); goto done; }
79
85};
86
92};
93
94static const struct ng_cmdlist ng_checksum_cmdlist[] = {
95 {
98 "getdlt",
99 NULL,
101 },
102 {
105 "setdlt",
107 NULL
108 },
109 {
112 "getconfig",
113 NULL,
115 },
116 {
119 "setconfig",
121 NULL
122 },
123 {
126 "getstats",
127 NULL,
129 },
130 {
133 "clrstats",
134 NULL,
135 NULL
136 },
137 {
140 "getclrstats",
141 NULL,
143 },
144 { 0 }
145};
146
147static struct ng_type typestruct = {
149 .name = NG_CHECKSUM_NODE_TYPE,
150 .constructor = ng_checksum_constructor,
151 .rcvmsg = ng_checksum_rcvmsg,
152 .shutdown = ng_checksum_shutdown,
153 .newhook = ng_checksum_newhook,
154 .rcvdata = ng_checksum_rcvdata,
155 .disconnect = ng_checksum_disconnect,
156 .cmdlist = ng_checksum_cmdlist,
157};
158
160
161static int
163{
164 priv_p priv;
165
166 priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK|M_ZERO);
167 priv->dlt = DLT_RAW;
168
170
171 return (0);
172}
173
174static int
175ng_checksum_newhook(node_p node, hook_p hook, const char *name)
176{
177 const priv_p priv = NG_NODE_PRIVATE(node);
178
179 if (strncmp(name, NG_CHECKSUM_HOOK_IN, strlen(NG_CHECKSUM_HOOK_IN)) == 0) {
180 priv->in = hook;
181 } else if (strncmp(name, NG_CHECKSUM_HOOK_OUT, strlen(NG_CHECKSUM_HOOK_OUT)) == 0) {
182 priv->out = hook;
183 } else
184 return (EINVAL);
185
186 return (0);
187}
188
189static int
191{
192 const priv_p priv = NG_NODE_PRIVATE(node);
193 struct ng_checksum_config *conf, *newconf;
194 struct ng_mesg *msg;
195 struct ng_mesg *resp = NULL;
196 int error = 0;
197
198 NGI_GET_MSG(item, msg);
199
201 ERROUT(EINVAL);
202
203 switch (msg->header.cmd)
204 {
206 NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK);
207
208 if (resp == NULL)
209 ERROUT(ENOMEM);
210
211 *((uint8_t *) resp->data) = priv->dlt;
212
213 break;
214
216 if (msg->header.arglen != sizeof(uint8_t))
217 ERROUT(EINVAL);
218
219 switch (*(uint8_t *) msg->data)
220 {
221 case DLT_EN10MB:
222 case DLT_RAW:
223 priv->dlt = *(uint8_t *) msg->data;
224 break;
225
226 default:
227 ERROUT(EINVAL);
228 }
229
230 break;
231
233 if (priv->conf == NULL)
234 ERROUT(0);
235
236 NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_config), M_WAITOK);
237
238 if (resp == NULL)
239 ERROUT(ENOMEM);
240
241 bcopy(priv->conf, resp->data, sizeof(struct ng_checksum_config));
242
243 break;
244
246 conf = (struct ng_checksum_config *) msg->data;
247
248 if (msg->header.arglen != sizeof(struct ng_checksum_config))
249 ERROUT(EINVAL);
250
253
254 newconf = malloc(sizeof(struct ng_checksum_config), M_NETGRAPH, M_WAITOK|M_ZERO);
255
256 bcopy(conf, newconf, sizeof(struct ng_checksum_config));
257
258 if (priv->conf)
259 free(priv->conf, M_NETGRAPH);
260
261 priv->conf = newconf;
262
263 break;
264
268 if (msg->header.cmd != NGM_CHECKSUM_CLR_STATS) {
269 NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_stats), M_WAITOK);
270
271 if (resp == NULL)
272 ERROUT(ENOMEM);
273
274 bcopy(&(priv->stats), resp->data, sizeof(struct ng_checksum_stats));
275 }
276
278 bzero(&(priv->stats), sizeof(struct ng_checksum_stats));
279
280 break;
281
282 default:
283 ERROUT(EINVAL);
284 }
285
286done:
287 NG_RESPOND_MSG(error, node, item, resp);
288 NG_FREE_MSG(msg);
289
290 return (error);
291}
292
293#define PULLUP_CHECK(mbuf, length) do { \
294 pullup_len += length; \
295 if (((mbuf)->m_pkthdr.len < pullup_len) || \
296 (pullup_len > MHLEN)) { \
297 return (EINVAL); \
298 } \
299 if ((mbuf)->m_len < pullup_len && \
300 (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \
301 return (ENOBUFS); \
302 } \
303} while (0)
304
305#ifdef INET
306static int
307checksum_ipv4(priv_p priv, struct mbuf *m, int l3_offset)
308{
309 struct ip *ip4;
310 int pullup_len;
311 int hlen, plen;
312 int processed = 0;
313
314 pullup_len = l3_offset;
315
316 PULLUP_CHECK(m, sizeof(struct ip));
317 ip4 = (struct ip *) mtodo(m, l3_offset);
318
319 if (ip4->ip_v != IPVERSION)
320 return (EOPNOTSUPP);
321
322 hlen = ip4->ip_hl << 2;
323 plen = ntohs(ip4->ip_len);
324
325 if (hlen < sizeof(struct ip) || m->m_pkthdr.len < l3_offset + plen)
326 return (EINVAL);
327
328 if (m->m_pkthdr.csum_flags & CSUM_IP) {
329 ip4->ip_sum = 0;
330
331 if ((priv->conf->csum_offload & CSUM_IP) == 0) {
332 if (hlen == sizeof(struct ip))
333 ip4->ip_sum = in_cksum_hdr(ip4);
334 else
335 ip4->ip_sum = in_cksum_skip(m, l3_offset + hlen, l3_offset);
336
337 m->m_pkthdr.csum_flags &= ~CSUM_IP;
338 }
339
340 processed = 1;
341 }
342
343 pullup_len = l3_offset + hlen;
344
345 /* We can not calculate a checksum fragmented packets */
346 if (ip4->ip_off & htons(IP_MF|IP_OFFMASK)) {
347 m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP);
348 return (0);
349 }
350
351 switch (ip4->ip_p)
352 {
353 case IPPROTO_TCP:
354 if (m->m_pkthdr.csum_flags & CSUM_TCP) {
355 struct tcphdr *th;
356
357 PULLUP_CHECK(m, sizeof(struct tcphdr));
358 th = (struct tcphdr *) mtodo(m, l3_offset + hlen);
359
360 th->th_sum = in_pseudo(ip4->ip_src.s_addr,
361 ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen));
362
363 if ((priv->conf->csum_offload & CSUM_TCP) == 0) {
364 th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen);
365 m->m_pkthdr.csum_flags &= ~CSUM_TCP;
366 }
367
368 processed = 1;
369 }
370
371 m->m_pkthdr.csum_flags &= ~CSUM_UDP;
372 break;
373
374 case IPPROTO_UDP:
375 if (m->m_pkthdr.csum_flags & CSUM_UDP) {
376 struct udphdr *uh;
377
378 PULLUP_CHECK(m, sizeof(struct udphdr));
379 uh = (struct udphdr *) mtodo(m, l3_offset + hlen);
380
381 uh->uh_sum = in_pseudo(ip4->ip_src.s_addr,
382 ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen));
383
384 if ((priv->conf->csum_offload & CSUM_UDP) == 0) {
385 uh->uh_sum = in_cksum_skip(m,
386 l3_offset + plen, l3_offset + hlen);
387
388 if (uh->uh_sum == 0)
389 uh->uh_sum = 0xffff;
390
391 m->m_pkthdr.csum_flags &= ~CSUM_UDP;
392 }
393
394 processed = 1;
395 }
396
397 m->m_pkthdr.csum_flags &= ~CSUM_TCP;
398 break;
399
400 default:
401 m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP);
402 break;
403 }
404
405 m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV6;
406
407 if (processed)
408 priv->stats.processed++;
409
410 return (0);
411}
412#endif /* INET */
413
414#ifdef INET6
415static int
416checksum_ipv6(priv_p priv, struct mbuf *m, int l3_offset)
417{
418 struct ip6_hdr *ip6;
419 struct ip6_ext *ip6e = NULL;
420 int pullup_len;
421 int hlen, plen;
422 int nxt;
423 int processed = 0;
424
425 pullup_len = l3_offset;
426
427 PULLUP_CHECK(m, sizeof(struct ip6_hdr));
428 ip6 = (struct ip6_hdr *) mtodo(m, l3_offset);
429
430 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)
431 return (EOPNOTSUPP);
432
433 hlen = sizeof(struct ip6_hdr);
434 plen = ntohs(ip6->ip6_plen) + hlen;
435
436 if (m->m_pkthdr.len < l3_offset + plen)
437 return (EINVAL);
438
439 nxt = ip6->ip6_nxt;
440
441 for (;;) {
442 switch (nxt)
443 {
444 case IPPROTO_DSTOPTS:
445 case IPPROTO_HOPOPTS:
446 case IPPROTO_ROUTING:
447 PULLUP_CHECK(m, sizeof(struct ip6_ext));
448 ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen);
449 nxt = ip6e->ip6e_nxt;
450 hlen += (ip6e->ip6e_len + 1) << 3;
451 pullup_len = l3_offset + hlen;
452 break;
453
454 case IPPROTO_AH:
455 PULLUP_CHECK(m, sizeof(struct ip6_ext));
456 ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen);
457 nxt = ip6e->ip6e_nxt;
458 hlen += (ip6e->ip6e_len + 2) << 2;
459 pullup_len = l3_offset + hlen;
460 break;
461
462 case IPPROTO_FRAGMENT:
463 /* We can not calculate a checksum fragmented packets */
464 m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6);
465 return (0);
466
467 default:
468 goto loopend;
469 }
470
471 if (nxt == 0)
472 return (EINVAL);
473 }
474
475loopend:
476
477 switch (nxt)
478 {
479 case IPPROTO_TCP:
480 if (m->m_pkthdr.csum_flags & CSUM_TCP_IPV6) {
481 struct tcphdr *th;
482
483 PULLUP_CHECK(m, sizeof(struct tcphdr));
484 th = (struct tcphdr *) mtodo(m, l3_offset + hlen);
485
486 th->th_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0);
487
488 if ((priv->conf->csum_offload & CSUM_TCP_IPV6) == 0) {
489 th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen);
490 m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6;
491 }
492
493 processed = 1;
494 }
495
496 m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6;
497 break;
498
499 case IPPROTO_UDP:
500 if (m->m_pkthdr.csum_flags & CSUM_UDP_IPV6) {
501 struct udphdr *uh;
502
503 PULLUP_CHECK(m, sizeof(struct udphdr));
504 uh = (struct udphdr *) mtodo(m, l3_offset + hlen);
505
506 uh->uh_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0);
507
508 if ((priv->conf->csum_offload & CSUM_UDP_IPV6) == 0) {
509 uh->uh_sum = in_cksum_skip(m,
510 l3_offset + plen, l3_offset + hlen);
511
512 if (uh->uh_sum == 0)
513 uh->uh_sum = 0xffff;
514
515 m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6;
516 }
517
518 processed = 1;
519 }
520
521 m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6;
522 break;
523
524 default:
525 m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6);
526 break;
527 }
528
529 m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV4;
530
531 if (processed)
532 priv->stats.processed++;
533
534 return (0);
535}
536#endif /* INET6 */
537
538#undef PULLUP_CHECK
539
540static int
542{
544 struct mbuf *m;
545 hook_p out;
546 int error = 0;
547
548 priv->stats.received++;
549
550 NGI_GET_M(item, m);
551
552#define PULLUP_CHECK(mbuf, length) do { \
553 pullup_len += length; \
554 if (((mbuf)->m_pkthdr.len < pullup_len) || \
555 (pullup_len > MHLEN)) { \
556 error = EINVAL; \
557 goto bypass; \
558 } \
559 if ((mbuf)->m_len < pullup_len && \
560 (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \
561 error = ENOBUFS; \
562 goto drop; \
563 } \
564} while (0)
565
566 if (!(priv->conf && hook == priv->in && m && (m->m_flags & M_PKTHDR)))
567 goto bypass;
568
569 m->m_pkthdr.csum_flags |= priv->conf->csum_flags;
570
571 if (m->m_pkthdr.csum_flags & (NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6))
572 {
573 struct ether_header *eh;
574 struct ng_checksum_vlan_header *vh;
575 int pullup_len = 0;
576 uint16_t etype;
577
578 m = m_unshare(m, M_NOWAIT);
579
580 if (m == NULL)
581 ERROUT(ENOMEM);
582
583 switch (priv->dlt)
584 {
585 case DLT_EN10MB:
586 PULLUP_CHECK(m, sizeof(struct ether_header));
587 eh = mtod(m, struct ether_header *);
588 etype = ntohs(eh->ether_type);
589
590 for (;;) { /* QinQ support */
591 switch (etype)
592 {
593 case 0x8100:
594 case 0x88A8:
595 case 0x9100:
596 PULLUP_CHECK(m, sizeof(struct ng_checksum_vlan_header));
597 vh = (struct ng_checksum_vlan_header *) mtodo(m,
598 pullup_len - sizeof(struct ng_checksum_vlan_header));
599 etype = ntohs(vh->etype);
600 break;
601
602 default:
603 goto loopend;
604 }
605 }
606loopend:
607#ifdef INET
608 if (etype == ETHERTYPE_IP &&
609 (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4)) {
610 error = checksum_ipv4(priv, m, pullup_len);
611 if (error == ENOBUFS)
612 goto drop;
613 } else
614#endif
615#ifdef INET6
616 if (etype == ETHERTYPE_IPV6 &&
617 (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6)) {
618 error = checksum_ipv6(priv, m, pullup_len);
619 if (error == ENOBUFS)
620 goto drop;
621 } else
622#endif
623 {
624 m->m_pkthdr.csum_flags &=
626 }
627
628 break;
629
630 case DLT_RAW:
631#ifdef INET
632 if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4)
633 {
634 error = checksum_ipv4(priv, m, pullup_len);
635
636 if (error == 0)
637 goto bypass;
638 else if (error == ENOBUFS)
639 goto drop;
640 }
641#endif
642#ifdef INET6
643 if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6)
644 {
645 error = checksum_ipv6(priv, m, pullup_len);
646
647 if (error == 0)
648 goto bypass;
649 else if (error == ENOBUFS)
650 goto drop;
651 }
652#endif
653 if (error)
654 m->m_pkthdr.csum_flags &=
656
657 break;
658
659 default:
660 ERROUT(EINVAL);
661 }
662 }
663
664#undef PULLUP_CHECK
665
666bypass:
667 out = NULL;
668
669 if (hook == priv->in) {
670 /* return frames on 'in' hook if 'out' not connected */
671 out = priv->out ? priv->out : priv->in;
672 } else if (hook == priv->out && priv->in) {
673 /* pass frames on 'out' hook if 'in' connected */
674 out = priv->in;
675 }
676
677 if (out == NULL)
678 ERROUT(0);
679
680 NG_FWD_NEW_DATA(error, item, out, m);
681
682 return (error);
683
684done:
685 NG_FREE_M(m);
686drop:
687 NG_FREE_ITEM(item);
688
689 priv->stats.dropped++;
690
691 return (error);
692}
693
694static int
696{
697 const priv_p priv = NG_NODE_PRIVATE(node);
698
699 NG_NODE_SET_PRIVATE(node, NULL);
700 NG_NODE_UNREF(node);
701
702 if (priv->conf)
703 free(priv->conf, M_NETGRAPH);
704
705 free(priv, M_NETGRAPH);
706
707 return (0);
708}
709
710static int
712{
713 priv_p priv;
714
716
717 if (hook == priv->in)
718 priv->in = NULL;
719
720 if (hook == priv->out)
721 priv->out = NULL;
722
723 if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
724 NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */
726
727 return (0);
728}
#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
static const struct ng_parse_struct_field ng_checksum_stats_fields[]
Definition: ng_checksum.c:88
static ng_shutdown_t ng_checksum_shutdown
Definition: ng_checksum.c:74
static const struct ng_parse_struct_field ng_checksum_config_type_fields[]
Definition: ng_checksum.c:81
static const struct ng_cmdlist ng_checksum_cmdlist[]
Definition: ng_checksum.c:94
#define ERROUT(x)
Definition: ng_checksum.c:78
static ng_disconnect_t ng_checksum_disconnect
Definition: ng_checksum.c:77
static const struct ng_parse_type ng_checksum_stats_type
Definition: ng_checksum.c:89
static ng_newhook_t ng_checksum_newhook
Definition: ng_checksum.c:75
static struct ng_type typestruct
Definition: ng_checksum.c:147
#define PULLUP_CHECK(mbuf, length)
Definition: ng_checksum.c:293
__FBSDID("$FreeBSD$")
static ng_rcvmsg_t ng_checksum_rcvmsg
Definition: ng_checksum.c:73
static const struct ng_parse_type ng_checksum_config_type
Definition: ng_checksum.c:82
NETGRAPH_INIT(checksum, &typestruct)
static ng_constructor_t ng_checksum_constructor
Definition: ng_checksum.c:72
static ng_rcvdata_t ng_checksum_rcvdata
Definition: ng_checksum.c:76
struct ng_checksum_priv * priv_p
Definition: ng_checksum.c:69
#define NG_CHECKSUM_NODE_TYPE
Definition: ng_checksum.h:33
#define NG_CHECKSUM_HOOK_OUT
Definition: ng_checksum.h:40
#define NG_CHECKSUM_CSUM_IPV6
Definition: ng_checksum.h:44
#define NG_CHECKSUM_HOOK_IN
Definition: ng_checksum.h:39
@ NGM_CHECKSUM_GETCONFIG
Definition: ng_checksum.h:50
@ NGM_CHECKSUM_SETCONFIG
Definition: ng_checksum.h:51
@ NGM_CHECKSUM_GET_STATS
Definition: ng_checksum.h:53
@ NGM_CHECKSUM_GETDLT
Definition: ng_checksum.h:48
@ NGM_CHECKSUM_SETDLT
Definition: ng_checksum.h:49
@ NGM_CHECKSUM_GETCLR_STATS
Definition: ng_checksum.h:52
@ NGM_CHECKSUM_CLR_STATS
Definition: ng_checksum.h:54
#define NG_CHECKSUM_STATS_TYPE
Definition: ng_checksum.h:65
#define NG_CHECKSUM_CSUM_IPV4
Definition: ng_checksum.h:43
#define NGM_CHECKSUM_COOKIE
Definition: ng_checksum.h:36
#define NG_CHECKSUM_CONFIG_TYPE
Definition: ng_checksum.h:59
#define NG_MKRESPONSE(rsp, msg, len, how)
Definition: ng_message.h:396
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
char *const name
Definition: ng_ppp.c:261
uint64_t csum_offload
Definition: ng_checksum.h:74
uint64_t csum_flags
Definition: ng_checksum.h:73
struct ng_checksum_config * conf
Definition: ng_checksum.c:65
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
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