Author: glebius
Date: Thu Apr  9 21:32:32 2015
New Revision: 281334
URL: https://svnweb.freebsd.org/changeset/base/281334

Log:
  In the ip_reass() do packet examination and adjusting before acquiring
  locks and doing lookups.
  
  Sponsored by: Nginx, Inc.

Modified:
  head/sys/netinet/ip_input.c

Modified: head/sys/netinet/ip_input.c
==============================================================================
--- head/sys/netinet/ip_input.c Thu Apr  9 21:30:11 2015        (r281333)
+++ head/sys/netinet/ip_input.c Thu Apr  9 21:32:32 2015        (r281334)
@@ -938,6 +938,41 @@ ip_reass(struct mbuf *m)
        ip = mtod(m, struct ip *);
        hlen = ip->ip_hl << 2;
 
+       /*
+        * Adjust ip_len to not reflect header,
+        * convert offset of this to bytes.
+        */
+       ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
+       if (ip->ip_off & htons(IP_MF)) {
+               /*
+                * Make sure that fragments have a data length
+                * that's a non-zero multiple of 8 bytes.
+                */
+               if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) {
+                       IPSTAT_INC(ips_toosmall); /* XXX */
+                       IPSTAT_INC(ips_fragdropped);
+                       m_freem(m);
+                       return (NULL);
+               }
+               m->m_flags |= M_IP_FRAG;
+       } else
+               m->m_flags &= ~M_IP_FRAG;
+       ip->ip_off = htons(ntohs(ip->ip_off) << 3);
+
+       /*
+        * Attempt reassembly; if it succeeds, proceed.
+        * ip_reass() will return a different mbuf.
+        */
+       IPSTAT_INC(ips_fragments);
+       m->m_pkthdr.PH_loc.ptr = ip;
+
+       /*
+        * Presence of header sizes in mbufs
+        * would confuse code below.
+        */
+       m->m_data += hlen;
+       m->m_len -= hlen;
+
        hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
        head = &V_ipq[hash].head;
        IPQ_LOCK(hash);
@@ -980,40 +1015,6 @@ ip_reass(struct mbuf *m)
 
 found:
        /*
-        * Adjust ip_len to not reflect header,
-        * convert offset of this to bytes.
-        */
-       ip->ip_len = htons(ntohs(ip->ip_len) - hlen);
-       if (ip->ip_off & htons(IP_MF)) {
-               /*
-                * Make sure that fragments have a data length
-                * that's a non-zero multiple of 8 bytes.
-                */
-               if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) {
-                       IPSTAT_INC(ips_toosmall); /* XXX */
-                       goto dropfrag;
-               }
-               m->m_flags |= M_IP_FRAG;
-       } else
-               m->m_flags &= ~M_IP_FRAG;
-       ip->ip_off = htons(ntohs(ip->ip_off) << 3);
-
-       /*
-        * Attempt reassembly; if it succeeds, proceed.
-        * ip_reass() will return a different mbuf.
-        */
-       IPSTAT_INC(ips_fragments);
-       m->m_pkthdr.PH_loc.ptr = ip;
-
-       /* Previous ip_reass() started here. */
-       /*
-        * Presence of header sizes in mbufs
-        * would confuse code below.
-        */
-       m->m_data += hlen;
-       m->m_len -= hlen;
-
-       /*
         * If first fragment to arrive, create a reassembly queue.
         */
        if (fp == NULL) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to