Author: bz
Date: Thu May 24 18:05:10 2012
New Revision: 235921
URL: http://svn.freebsd.org/changeset/base/235921

Log:
  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

Modified:
  head/sys/netinet6/in6_cksum.c

Modified: head/sys/netinet6/in6_cksum.c
==============================================================================
--- head/sys/netinet6/in6_cksum.c       Thu May 24 17:39:54 2012        
(r235920)
+++ head/sys/netinet6/in6_cksum.c       Thu May 24 18:05:10 2012        
(r235921)
@@ -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 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, 
        /*
         * 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.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to