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
This commit is contained in:
parent
e9651b7649
commit
2889eb8bdf
@ -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,43 +110,39 @@ 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;
|
||||
sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
|
||||
sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
|
||||
|
||||
/* IPv6 destination address */
|
||||
in6 = ip6->ip6_dst;
|
||||
in6_clearscope(&in6);
|
||||
w = (u_int16_t *)&in6;
|
||||
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];
|
||||
/* 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. */
|
||||
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];
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user