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"