summaryrefslogtreecommitdiffstats
path: root/sys/netinet6/in6_cksum.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2012-05-24 18:05:10 +0000
committerbz <bz@FreeBSD.org>2012-05-24 18:05:10 +0000
commit0a74a9f5597ed88e7f94539d3ec49ed7ed18b66b (patch)
tree4f5cf34fa9a6731008e39e1ec9776428171f4df1 /sys/netinet6/in6_cksum.c
parent1759916fa95d3f268c693fce26434f39be74be46 (diff)
downloadFreeBSD-src-0a74a9f5597ed88e7f94539d3ec49ed7ed18b66b.zip
FreeBSD-src-0a74a9f5597ed88e7f94539d3ec49ed7ed18b66b.tar.gz
MFp4 bz_ipv6_fast:
Optimize in6_cksum(), re-ordering work and limiting variable initialization, removing a bzero() for mostly re-initialized struct values, making use of the newly introduced in6_getscope(), as well as converting an if/panic to a KASSERT(). Sponsored by: The FreeBSD Foundation Sponsored by: iXsystems Reviewed by: gnn (as part of the whole) MFC After: 3 days
Diffstat (limited to 'sys/netinet6/in6_cksum.c')
-rw-r--r--sys/netinet6/in6_cksum.c58
1 files changed, 27 insertions, 31 deletions
diff --git a/sys/netinet6/in6_cksum.c b/sys/netinet6/in6_cksum.c
index 9cb97bd..034848b 100644
--- a/sys/netinet6/in6_cksum.c
+++ b/sys/netinet6/in6_cksum.c
@@ -89,12 +89,10 @@ __FBSDID("$FreeBSD$");
int
in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
{
- u_int16_t *w;
- int sum = 0;
- int mlen = 0;
- int byte_swapped = 0;
struct ip6_hdr *ip6;
- struct in6_addr in6;
+ u_int16_t *w, scope;
+ int byte_swapped, mlen;
+ int sum;
union {
u_int16_t phs[4];
struct {
@@ -112,42 +110,38 @@ in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
u_int32_t l;
} l_util;
- /* sanity check */
- if (m->m_pkthdr.len < off + len) {
- panic("in6_cksum: mbuf len (%d) < off+len (%d+%d)",
- m->m_pkthdr.len, off, len);
- }
-
- bzero(&uph, sizeof(uph));
+ /* Sanity check. */
+ KASSERT(m->m_pkthdr.len >= off + len, ("%s: mbuf len (%d) < off(%d)+"
+ "len(%d)", __func__, m->m_pkthdr.len, off, len));
/*
* First create IP6 pseudo header and calculate a summary.
*/
- ip6 = mtod(m, struct ip6_hdr *);
uph.ph.ph_len = htonl(len);
+ uph.ph.ph_zero[0] = uph.ph.ph_zero[1] = uph.ph.ph_zero[2] = 0;
uph.ph.ph_nxt = nxt;
- /*
- * IPv6 source address.
- * XXX: we'd like to avoid copying the address, but we can't due to
- * the possibly embedded scope zone ID.
- */
- in6 = ip6->ip6_src;
- in6_clearscope(&in6);
- w = (u_int16_t *)&in6;
+ /* Payload length and upper layer identifier. */
+ sum = uph.phs[0]; sum += uph.phs[1];
+ sum += uph.phs[2]; sum += uph.phs[3];
+
+ ip6 = mtod(m, struct ip6_hdr *);
+
+ /* IPv6 source address. */
+ scope = in6_getscope(&ip6->ip6_src);
+ w = (u_int16_t *)&ip6->ip6_src;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
+ if (scope != 0)
+ sum -= scope;
- /* IPv6 destination address */
- in6 = ip6->ip6_dst;
- in6_clearscope(&in6);
- w = (u_int16_t *)&in6;
+ /* IPv6 destination address. */
+ scope = in6_getscope(&ip6->ip6_dst);
+ w = (u_int16_t *)&ip6->ip6_dst;
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
-
- /* Payload length and upper layer identifier */
- sum += uph.phs[0]; sum += uph.phs[1];
- sum += uph.phs[2]; sum += uph.phs[3];
+ if (scope != 0)
+ sum -= scope;
/*
* Secondly calculate a summary of the first mbuf excluding offset.
@@ -167,14 +161,16 @@ in6_cksum(struct mbuf *m, u_int8_t nxt, u_int32_t off, u_int32_t len)
/*
* Force to even boundary.
*/
- if ((1 & (long) w) && (mlen > 0)) {
+ if ((1 & (long)w) && (mlen > 0)) {
REDUCE;
sum <<= 8;
s_util.c[0] = *(u_char *)w;
w = (u_int16_t *)((char *)w + 1);
mlen--;
byte_swapped = 1;
- }
+ } else
+ byte_swapped = 0;
+
/*
* Unroll the loop to make overhead from
* branches &c small.
OpenPOWER on IntegriCloud