From 9ef7f40b515746ee678c715ce07e3accdeb87bf5 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 2 Dec 2016 05:36:37 +0000 Subject: MFH: r303612 netgraph module for reconstructing checksums PR: 206108 Submitted by: Dmitry Vagin daemon.hammer@ya.ru --- sys/netgraph/ng_checksum.c | 729 +++++++++++++++++++++++++++++++++++++++++++++ sys/netgraph/ng_checksum.h | 88 ++++++ 2 files changed, 817 insertions(+) create mode 100644 sys/netgraph/ng_checksum.c create mode 100644 sys/netgraph/ng_checksum.h (limited to 'sys/netgraph') diff --git a/sys/netgraph/ng_checksum.c b/sys/netgraph/ng_checksum.c new file mode 100644 index 0000000..c7fecb0 --- /dev/null +++ b/sys/netgraph/ng_checksum.c @@ -0,0 +1,729 @@ +/*- + * Copyright (c) 2015 Dmitry Vagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_inet.h" +#include "opt_inet6.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* private data */ +struct ng_checksum_priv { + hook_p in; + hook_p out; + uint8_t dlt; /* DLT_XXX from bpf.h */ + struct ng_checksum_config *conf; + struct ng_checksum_stats stats; +}; + +typedef struct ng_checksum_priv *priv_p; + +/* Netgraph methods */ +static ng_constructor_t ng_checksum_constructor; +static ng_rcvmsg_t ng_checksum_rcvmsg; +static ng_shutdown_t ng_checksum_shutdown; +static ng_newhook_t ng_checksum_newhook; +static ng_rcvdata_t ng_checksum_rcvdata; +static ng_disconnect_t ng_checksum_disconnect; + +#define ERROUT(x) { error = (x); goto done; } + +static const struct ng_parse_struct_field ng_checksum_config_type_fields[] + = NG_CHECKSUM_CONFIG_TYPE; +static const struct ng_parse_type ng_checksum_config_type = { + &ng_parse_struct_type, + &ng_checksum_config_type_fields +}; + +static const struct ng_parse_struct_field ng_checksum_stats_fields[] + = NG_CHECKSUM_STATS_TYPE; +static const struct ng_parse_type ng_checksum_stats_type = { + &ng_parse_struct_type, + &ng_checksum_stats_fields +}; + +static const struct ng_cmdlist ng_checksum_cmdlist[] = { + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_GETDLT, + "getdlt", + NULL, + &ng_parse_uint8_type + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_SETDLT, + "setdlt", + &ng_parse_uint8_type, + NULL + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_GETCONFIG, + "getconfig", + NULL, + &ng_checksum_config_type + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_SETCONFIG, + "setconfig", + &ng_checksum_config_type, + NULL + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_GET_STATS, + "getstats", + NULL, + &ng_checksum_stats_type + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_CLR_STATS, + "clrstats", + NULL, + NULL + }, + { + NGM_CHECKSUM_COOKIE, + NGM_CHECKSUM_GETCLR_STATS, + "getclrstats", + NULL, + &ng_checksum_stats_type + }, + { 0 } +}; + +static struct ng_type typestruct = { + .version = NG_ABI_VERSION, + .name = NG_CHECKSUM_NODE_TYPE, + .constructor = ng_checksum_constructor, + .rcvmsg = ng_checksum_rcvmsg, + .shutdown = ng_checksum_shutdown, + .newhook = ng_checksum_newhook, + .rcvdata = ng_checksum_rcvdata, + .disconnect = ng_checksum_disconnect, + .cmdlist = ng_checksum_cmdlist, +}; + +NETGRAPH_INIT(checksum, &typestruct); + +static int +ng_checksum_constructor(node_p node) +{ + priv_p priv; + + priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK|M_ZERO); + priv->dlt = DLT_RAW; + + NG_NODE_SET_PRIVATE(node, priv); + + return (0); +} + +static int +ng_checksum_newhook(node_p node, hook_p hook, const char *name) +{ + const priv_p priv = NG_NODE_PRIVATE(node); + + if (strncmp(name, NG_CHECKSUM_HOOK_IN, strlen(NG_CHECKSUM_HOOK_IN)) == 0) { + priv->in = hook; + } else if (strncmp(name, NG_CHECKSUM_HOOK_OUT, strlen(NG_CHECKSUM_HOOK_OUT)) == 0) { + priv->out = hook; + } else + return (EINVAL); + + return (0); +} + +static int +ng_checksum_rcvmsg(node_p node, item_p item, hook_p lasthook) +{ + const priv_p priv = NG_NODE_PRIVATE(node); + struct ng_checksum_config *conf, *newconf; + struct ng_mesg *msg; + struct ng_mesg *resp = NULL; + int error = 0; + + NGI_GET_MSG(item, msg); + + if (msg->header.typecookie != NGM_CHECKSUM_COOKIE) + ERROUT(EINVAL); + + switch (msg->header.cmd) + { + case NGM_CHECKSUM_GETDLT: + NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK); + + if (resp == NULL) + ERROUT(ENOMEM); + + *((uint8_t *) resp->data) = priv->dlt; + + break; + + case NGM_CHECKSUM_SETDLT: + if (msg->header.arglen != sizeof(uint8_t)) + ERROUT(EINVAL); + + switch (*(uint8_t *) msg->data) + { + case DLT_EN10MB: + case DLT_RAW: + priv->dlt = *(uint8_t *) msg->data; + break; + + default: + ERROUT(EINVAL); + } + + break; + + case NGM_CHECKSUM_GETCONFIG: + if (priv->conf == NULL) + ERROUT(0); + + NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_config), M_WAITOK); + + if (resp == NULL) + ERROUT(ENOMEM); + + bcopy(priv->conf, resp->data, sizeof(struct ng_checksum_config)); + + break; + + case NGM_CHECKSUM_SETCONFIG: + conf = (struct ng_checksum_config *) msg->data; + + if (msg->header.arglen != sizeof(struct ng_checksum_config)) + ERROUT(EINVAL); + + conf->csum_flags &= NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6; + conf->csum_offload &= NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6; + + newconf = malloc(sizeof(struct ng_checksum_config), M_NETGRAPH, M_WAITOK|M_ZERO); + + bcopy(conf, newconf, sizeof(struct ng_checksum_config)); + + if (priv->conf) + free(priv->conf, M_NETGRAPH); + + priv->conf = newconf; + + break; + + case NGM_CHECKSUM_GET_STATS: + case NGM_CHECKSUM_CLR_STATS: + case NGM_CHECKSUM_GETCLR_STATS: + if (msg->header.cmd != NGM_CHECKSUM_CLR_STATS) { + NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_stats), M_WAITOK); + + if (resp == NULL) + ERROUT(ENOMEM); + + bcopy(&(priv->stats), resp->data, sizeof(struct ng_checksum_stats)); + } + + if (msg->header.cmd != NGM_CHECKSUM_GET_STATS) + bzero(&(priv->stats), sizeof(struct ng_checksum_stats)); + + break; + + default: + ERROUT(EINVAL); + } + +done: + NG_RESPOND_MSG(error, node, item, resp); + NG_FREE_MSG(msg); + + return (error); +} + +#define PULLUP_CHECK(mbuf, length) do { \ + pullup_len += length; \ + if (((mbuf)->m_pkthdr.len < pullup_len) || \ + (pullup_len > MHLEN)) { \ + return (EINVAL); \ + } \ + if ((mbuf)->m_len < pullup_len && \ + (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \ + return (ENOBUFS); \ + } \ +} while (0) + +#ifdef INET +static int +checksum_ipv4(priv_p priv, struct mbuf *m, int l3_offset) +{ + struct ip *ip4; + int pullup_len; + int hlen, plen; + int processed = 0; + + pullup_len = l3_offset; + + PULLUP_CHECK(m, sizeof(struct ip)); + ip4 = (struct ip *) mtodo(m, l3_offset); + + if (ip4->ip_v != IPVERSION) + return (EOPNOTSUPP); + + hlen = ip4->ip_hl << 2; + plen = ntohs(ip4->ip_len); + + if (hlen < sizeof(struct ip) || m->m_pkthdr.len < l3_offset + plen) + return (EINVAL); + + if (m->m_pkthdr.csum_flags & CSUM_IP) { + ip4->ip_sum = 0; + + if ((priv->conf->csum_offload & CSUM_IP) == 0) { + if (hlen == sizeof(struct ip)) + ip4->ip_sum = in_cksum_hdr(ip4); + else + ip4->ip_sum = in_cksum_skip(m, l3_offset + hlen, l3_offset); + + m->m_pkthdr.csum_flags &= ~CSUM_IP; + } + + processed = 1; + } + + pullup_len = l3_offset + hlen; + + /* We can not calculate a checksum fragmented packets */ + if (ip4->ip_off & htons(IP_MF|IP_OFFMASK)) { + m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP); + return (0); + } + + switch (ip4->ip_p) + { + case IPPROTO_TCP: + if (m->m_pkthdr.csum_flags & CSUM_TCP) { + struct tcphdr *th; + + PULLUP_CHECK(m, sizeof(struct tcphdr)); + th = (struct tcphdr *) mtodo(m, l3_offset + hlen); + + th->th_sum = in_pseudo(ip4->ip_src.s_addr, + ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen)); + + if ((priv->conf->csum_offload & CSUM_TCP) == 0) { + th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen); + m->m_pkthdr.csum_flags &= ~CSUM_TCP; + } + + processed = 1; + } + + m->m_pkthdr.csum_flags &= ~CSUM_UDP; + break; + + case IPPROTO_UDP: + if (m->m_pkthdr.csum_flags & CSUM_UDP) { + struct udphdr *uh; + + PULLUP_CHECK(m, sizeof(struct udphdr)); + uh = (struct udphdr *) mtodo(m, l3_offset + hlen); + + uh->uh_sum = in_pseudo(ip4->ip_src.s_addr, + ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen)); + + if ((priv->conf->csum_offload & CSUM_UDP) == 0) { + uh->uh_sum = in_cksum_skip(m, + l3_offset + plen, l3_offset + hlen); + + if (uh->uh_sum == 0) + uh->uh_sum = 0xffff; + + m->m_pkthdr.csum_flags &= ~CSUM_UDP; + } + + processed = 1; + } + + m->m_pkthdr.csum_flags &= ~CSUM_TCP; + break; + + default: + m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP); + break; + } + + m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV6; + + if (processed) + priv->stats.processed++; + + return (0); +} +#endif /* INET */ + +#ifdef INET6 +static int +checksum_ipv6(priv_p priv, struct mbuf *m, int l3_offset) +{ + struct ip6_hdr *ip6; + struct ip6_ext *ip6e = NULL; + int pullup_len; + int hlen, plen; + int nxt; + int processed = 0; + + pullup_len = l3_offset; + + PULLUP_CHECK(m, sizeof(struct ip6_hdr)); + ip6 = (struct ip6_hdr *) mtodo(m, l3_offset); + + if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) + return (EOPNOTSUPP); + + hlen = sizeof(struct ip6_hdr); + plen = ntohs(ip6->ip6_plen) + hlen; + + if (m->m_pkthdr.len < l3_offset + plen) + return (EINVAL); + + nxt = ip6->ip6_nxt; + + for (;;) { + switch (nxt) + { + case IPPROTO_DSTOPTS: + case IPPROTO_HOPOPTS: + case IPPROTO_ROUTING: + PULLUP_CHECK(m, sizeof(struct ip6_ext)); + ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen); + nxt = ip6e->ip6e_nxt; + hlen += (ip6e->ip6e_len + 1) << 3; + pullup_len = l3_offset + hlen; + break; + + case IPPROTO_AH: + PULLUP_CHECK(m, sizeof(struct ip6_ext)); + ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen); + nxt = ip6e->ip6e_nxt; + hlen += (ip6e->ip6e_len + 2) << 2; + pullup_len = l3_offset + hlen; + break; + + case IPPROTO_FRAGMENT: + /* We can not calculate a checksum fragmented packets */ + m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6); + return (0); + + default: + goto loopend; + } + + if (nxt == 0) + return (EINVAL); + } + +loopend: + + switch (nxt) + { + case IPPROTO_TCP: + if (m->m_pkthdr.csum_flags & CSUM_TCP_IPV6) { + struct tcphdr *th; + + PULLUP_CHECK(m, sizeof(struct tcphdr)); + th = (struct tcphdr *) mtodo(m, l3_offset + hlen); + + th->th_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0); + + if ((priv->conf->csum_offload & CSUM_TCP_IPV6) == 0) { + th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen); + m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6; + } + + processed = 1; + } + + m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6; + break; + + case IPPROTO_UDP: + if (m->m_pkthdr.csum_flags & CSUM_UDP_IPV6) { + struct udphdr *uh; + + PULLUP_CHECK(m, sizeof(struct udphdr)); + uh = (struct udphdr *) mtodo(m, l3_offset + hlen); + + uh->uh_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0); + + if ((priv->conf->csum_offload & CSUM_UDP_IPV6) == 0) { + uh->uh_sum = in_cksum_skip(m, + l3_offset + plen, l3_offset + hlen); + + if (uh->uh_sum == 0) + uh->uh_sum = 0xffff; + + m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6; + } + + processed = 1; + } + + m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6; + break; + + default: + m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6); + break; + } + + m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV4; + + if (processed) + priv->stats.processed++; + + return (0); +} +#endif /* INET6 */ + +#undef PULLUP_CHECK + +static int +ng_checksum_rcvdata(hook_p hook, item_p item) +{ + const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); + struct mbuf *m; + hook_p out; + int error = 0; + + priv->stats.received++; + + NGI_GET_M(item, m); + +#define PULLUP_CHECK(mbuf, length) do { \ + pullup_len += length; \ + if (((mbuf)->m_pkthdr.len < pullup_len) || \ + (pullup_len > MHLEN)) { \ + error = EINVAL; \ + goto bypass; \ + } \ + if ((mbuf)->m_len < pullup_len && \ + (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) { \ + error = ENOBUFS; \ + goto drop; \ + } \ +} while (0) + + if (!(priv->conf && hook == priv->in && m && (m->m_flags & M_PKTHDR))) + goto bypass; + + m->m_pkthdr.csum_flags |= priv->conf->csum_flags; + + if (m->m_pkthdr.csum_flags & (NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6)) + { + struct ether_header *eh; + struct ng_checksum_vlan_header *vh; + int pullup_len = 0; + uint16_t etype; + + m = m_unshare(m, M_NOWAIT); + + if (m == NULL) + ERROUT(ENOMEM); + + switch (priv->dlt) + { + case DLT_EN10MB: + PULLUP_CHECK(m, sizeof(struct ether_header)); + eh = mtod(m, struct ether_header *); + etype = ntohs(eh->ether_type); + + for (;;) { /* QinQ support */ + switch (etype) + { + case 0x8100: + case 0x88A8: + case 0x9100: + PULLUP_CHECK(m, sizeof(struct ng_checksum_vlan_header)); + vh = (struct ng_checksum_vlan_header *) mtodo(m, + pullup_len - sizeof(struct ng_checksum_vlan_header)); + etype = ntohs(vh->etype); + break; + + default: + goto loopend; + } + } +loopend: +#ifdef INET + if (etype == ETHERTYPE_IP && + (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4)) { + error = checksum_ipv4(priv, m, pullup_len); + if (error == ENOBUFS) + goto drop; + } else +#endif +#ifdef INET6 + if (etype == ETHERTYPE_IPV6 && + (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6)) { + error = checksum_ipv6(priv, m, pullup_len); + if (error == ENOBUFS) + goto drop; + } else +#endif + { + m->m_pkthdr.csum_flags &= + ~(NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6); + } + + break; + + case DLT_RAW: +#ifdef INET + if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4) + { + error = checksum_ipv4(priv, m, pullup_len); + + if (error == 0) + goto bypass; + else if (error == ENOBUFS) + goto drop; + } +#endif +#ifdef INET6 + if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6) + { + error = checksum_ipv6(priv, m, pullup_len); + + if (error == 0) + goto bypass; + else if (error == ENOBUFS) + goto drop; + } +#endif + if (error) + m->m_pkthdr.csum_flags &= + ~(NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6); + + break; + + default: + ERROUT(EINVAL); + } + } + +#undef PULLUP_CHECK + +bypass: + out = NULL; + + if (hook == priv->in) { + /* return frames on 'in' hook if 'out' not connected */ + out = priv->out ? priv->out : priv->in; + } else if (hook == priv->out && priv->in) { + /* pass frames on 'out' hook if 'in' connected */ + out = priv->in; + } + + if (out == NULL) + ERROUT(0); + + NG_FWD_NEW_DATA(error, item, out, m); + + return (error); + +done: +drop: + NG_FREE_ITEM(item); + NG_FREE_M(m); + + priv->stats.dropped++; + + return (error); +} + +static int +ng_checksum_shutdown(node_p node) +{ + const priv_p priv = NG_NODE_PRIVATE(node); + + NG_NODE_SET_PRIVATE(node, NULL); + NG_NODE_UNREF(node); + + if (priv->conf) + free(priv->conf, M_NETGRAPH); + + free(priv, M_NETGRAPH); + + return (0); +} + +static int +ng_checksum_disconnect(hook_p hook) +{ + priv_p priv; + + priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); + + if (hook == priv->in) + priv->in = NULL; + + if (hook == priv->out) + priv->out = NULL; + + if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 && + NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */ + ng_rmnode_self(NG_HOOK_NODE(hook)); + + return (0); +} diff --git a/sys/netgraph/ng_checksum.h b/sys/netgraph/ng_checksum.h new file mode 100644 index 0000000..8bd5dd9 --- /dev/null +++ b/sys/netgraph/ng_checksum.h @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2015 Dmitry Vagin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NETGRAPH_NG_CHECKSUM_H_ +#define _NETGRAPH_NG_CHECKSUM_H_ + +/* Node type name. */ +#define NG_CHECKSUM_NODE_TYPE "checksum" + +/* Node type cookie. */ +#define NGM_CHECKSUM_COOKIE 439419912 + +/* Hook names */ +#define NG_CHECKSUM_HOOK_IN "in" +#define NG_CHECKSUM_HOOK_OUT "out" + +/* Checksum flags */ +#define NG_CHECKSUM_CSUM_IPV4 (CSUM_IP|CSUM_TCP|CSUM_UDP) +#define NG_CHECKSUM_CSUM_IPV6 (CSUM_TCP_IPV6|CSUM_UDP_IPV6) + +/* Netgraph commands understood by this node type */ +enum { + NGM_CHECKSUM_GETDLT = 1, + NGM_CHECKSUM_SETDLT, + NGM_CHECKSUM_GETCONFIG, + NGM_CHECKSUM_SETCONFIG, + NGM_CHECKSUM_GETCLR_STATS, + NGM_CHECKSUM_GET_STATS, + NGM_CHECKSUM_CLR_STATS, +}; + +/* Parsing declarations */ + +#define NG_CHECKSUM_CONFIG_TYPE { \ + { "csum_flags", &ng_parse_uint64_type }, \ + { "csum_offload", &ng_parse_uint64_type }, \ + { NULL } \ +} + +#define NG_CHECKSUM_STATS_TYPE { \ + { "Received", &ng_parse_uint64_type }, \ + { "Processed", &ng_parse_uint64_type }, \ + { "Dropped", &ng_parse_uint64_type }, \ + { NULL } \ +} + +struct ng_checksum_config { + uint64_t csum_flags; + uint64_t csum_offload; +}; + +struct ng_checksum_stats { + uint64_t received; + uint64_t processed; + uint64_t dropped; +}; + +struct ng_checksum_vlan_header { + u_int16_t tag; + u_int16_t etype; +}; + +#endif /* _NETGRAPH_NG_CHECKSUM_H_ */ -- cgit v1.1 From d70c98850f70ec4b1f57ba7a96b57aadf970535c Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 2 Dec 2016 05:42:49 +0000 Subject: MFH: r303611 slite style changes. There is an incoming patch that rewrites a lot of this module and I want to get the style and whitespace changes in a separate commit (or maybe more). PR: 206185 Submitted by: Dmitry Vagin --- sys/netgraph/ng_patch.c | 17 ++++++++++------- sys/netgraph/ng_patch.h | 36 ++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 25 deletions(-) (limited to 'sys/netgraph') diff --git a/sys/netgraph/ng_patch.c b/sys/netgraph/ng_patch.c index 8239dd6..691bd60 100644 --- a/sys/netgraph/ng_patch.c +++ b/sys/netgraph/ng_patch.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2010 by Maxim Ignatenko + * Copyright (c) 2010 Maxim Ignatenko * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,11 +50,12 @@ static int ng_patch_config_getlen(const struct ng_parse_type *type, const u_char *start, const u_char *buf) { - const struct ng_patch_config *p; + const struct ng_patch_config *conf; - p = (const struct ng_patch_config *)(buf - + conf = (const struct ng_patch_config *)(buf - offsetof(struct ng_patch_config, ops)); - return (p->count); + + return (conf->count); } static const struct ng_parse_struct_field ng_patch_op_type_fields[] @@ -64,13 +65,13 @@ static const struct ng_parse_type ng_patch_op_type = { &ng_patch_op_type_fields }; -static const struct ng_parse_array_info ng_patch_confarr_info = { +static const struct ng_parse_array_info ng_patch_ops_array_info = { &ng_patch_op_type, &ng_patch_config_getlen }; -static const struct ng_parse_type ng_patch_confarr_type = { +static const struct ng_parse_type ng_patch_ops_array_type = { &ng_parse_array_type, - &ng_patch_confarr_info + &ng_patch_ops_array_info }; static const struct ng_parse_struct_field ng_patch_config_type_fields[] @@ -137,6 +138,7 @@ static struct ng_type typestruct = { .disconnect = ng_patch_disconnect, .cmdlist = ng_patch_cmdlist, }; + NETGRAPH_INIT(patch, &typestruct); union patch_val { @@ -146,6 +148,7 @@ union patch_val { uint64_t v8; }; +/* private data */ struct ng_patch_priv { hook_p in; hook_p out; diff --git a/sys/netgraph/ng_patch.h b/sys/netgraph/ng_patch.h index 28d9033..7bbe264 100644 --- a/sys/netgraph/ng_patch.h +++ b/sys/netgraph/ng_patch.h @@ -57,7 +57,7 @@ enum { NG_PATCH_MODE_DIV = 5, NG_PATCH_MODE_NEG = 6, NG_PATCH_MODE_AND = 7, - NG_PATCH_MODE_OR = 8, + NG_PATCH_MODE_OR = 8, NG_PATCH_MODE_XOR = 9, NG_PATCH_MODE_SHL = 10, NG_PATCH_MODE_SHR = 11 @@ -66,16 +66,16 @@ enum { struct ng_patch_op { uint64_t value; uint32_t offset; - uint16_t length; /* 1,2,4 or 8 (bytes) */ + uint16_t length; /* 1, 2, 4 or 8 (bytes) */ uint16_t mode; }; -#define NG_PATCH_OP_TYPE_INFO { \ - { "value", &ng_parse_uint64_type }, \ - { "offset", &ng_parse_uint32_type }, \ - { "length", &ng_parse_uint16_type }, \ - { "mode", &ng_parse_uint16_type }, \ - { NULL } \ +#define NG_PATCH_OP_TYPE_INFO { \ + { "value", &ng_parse_uint64_type }, \ + { "offset", &ng_parse_uint32_type }, \ + { "length", &ng_parse_uint16_type }, \ + { "mode", &ng_parse_uint16_type }, \ + { NULL } \ } struct ng_patch_config { @@ -84,11 +84,11 @@ struct ng_patch_config { struct ng_patch_op ops[]; }; -#define NG_PATCH_CONFIG_TYPE_INFO { \ - { "count", &ng_parse_uint32_type }, \ - { "csum_flags", &ng_parse_uint32_type }, \ - { "ops", &ng_patch_confarr_type }, \ - { NULL } \ +#define NG_PATCH_CONFIG_TYPE_INFO { \ + { "count", &ng_parse_uint32_type }, \ + { "csum_flags", &ng_parse_uint64_type }, \ + { "ops", &ng_patch_ops_array_type }, \ + { NULL } \ } struct ng_patch_stats { @@ -97,11 +97,11 @@ struct ng_patch_stats { uint64_t dropped; }; -#define NG_PATCH_STATS_TYPE_INFO { \ - { "received", &ng_parse_uint64_type }, \ - { "patched", &ng_parse_uint64_type }, \ - { "dropped", &ng_parse_uint64_type }, \ - { NULL } \ +#define NG_PATCH_STATS_TYPE_INFO { \ + { "Received", &ng_parse_uint64_type }, \ + { "Patched", &ng_parse_uint64_type }, \ + { "Dropped", &ng_parse_uint64_type }, \ + { NULL } \ } #endif /* _NETGRAPH_NG_PATCH_H_ */ -- cgit v1.1