From owner-svn-src-all@FreeBSD.ORG Wed Jan 28 10:41:11 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1A06C106564A; Wed, 28 Jan 2009 10:41:11 +0000 (UTC) (envelope-from vanhu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 07F0F8FC0C; Wed, 28 Jan 2009 10:41:11 +0000 (UTC) (envelope-from vanhu@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0SAfA6I017540; Wed, 28 Jan 2009 10:41:10 GMT (envelope-from vanhu@svn.freebsd.org) Received: (from vanhu@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0SAfApB017539; Wed, 28 Jan 2009 10:41:10 GMT (envelope-from vanhu@svn.freebsd.org) Message-Id: <200901281041.n0SAfApB017539@svn.freebsd.org> From: VANHULLEBUS Yvan Date: Wed, 28 Jan 2009 10:41:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187815 - head/sys/netipsec X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Jan 2009 10:41:12 -0000 Author: vanhu Date: Wed Jan 28 10:41:10 2009 New Revision: 187815 URL: http://svn.freebsd.org/changeset/base/187815 Log: Remove remain <= MHLEN restriction in m_makespace(), which caused assert with big packets PR: kern/124609 Submitted by: fabien.thomas@netasq.com Approved by: gnn(mentor) Obtained from: NetBSD MFC after: 1 month Modified: head/sys/netipsec/ipsec_mbuf.c Modified: head/sys/netipsec/ipsec_mbuf.c ============================================================================== --- head/sys/netipsec/ipsec_mbuf.c Wed Jan 28 09:33:00 2009 (r187814) +++ head/sys/netipsec/ipsec_mbuf.c Wed Jan 28 10:41:10 2009 (r187815) @@ -75,66 +75,67 @@ m_makespace(struct mbuf *m0, int skip, i */ remain = m->m_len - skip; /* data to move */ if (hlen > M_TRAILINGSPACE(m)) { - struct mbuf *n; + struct mbuf *n0, *n, **np; + int todo, len, done, alloc; + + n0 = NULL; + np = &n0; + alloc = 0; + done = 0; + todo = remain; + while (todo > 0) { + if (todo > MHLEN) { + n = m_getcl(M_DONTWAIT, m->m_type, 0); + len = MCLBYTES; + } + else { + n = m_get(M_DONTWAIT, m->m_type); + len = MHLEN; + } + if (n == NULL) { + m_freem(n0); + return NULL; + } + *np = n; + np = &n->m_next; + alloc++; + len = min(todo, len); + memcpy(n->m_data, mtod(m, char *) + skip + done, len); + n->m_len = len; + done += len; + todo -= len; + } - /* XXX code doesn't handle clusters XXX */ - IPSEC_ASSERT(remain < MLEN, ("remainder too big: %u", remain)); - /* - * Not enough space in m, split the contents - * of m, inserting new mbufs as required. - * - * NB: this ignores mbuf types. - */ - MGET(n, M_DONTWAIT, MT_DATA); - if (n == NULL) - return (NULL); - n->m_next = m->m_next; /* splice new mbuf */ - m->m_next = n; - V_ipsec4stat.ips_mbinserted++; if (hlen <= M_TRAILINGSPACE(m) + remain) { - /* - * New header fits in the old mbuf if we copy - * the remainder; just do the copy to the new - * mbuf and we're good to go. - */ - memcpy(mtod(n, caddr_t), - mtod(m, caddr_t) + skip, remain); - n->m_len = remain; m->m_len = skip + hlen; *off = skip; - } else { - /* - * No space in the old mbuf for the new header. - * Make space in the new mbuf and check the - * remainder'd data fits too. If not then we - * must allocate an additional mbuf (yech). - */ - n->m_len = 0; - if (remain + hlen > M_TRAILINGSPACE(n)) { - struct mbuf *n2; - - MGET(n2, M_DONTWAIT, MT_DATA); - /* NB: new mbuf is on chain, let caller free */ - if (n2 == NULL) - return (NULL); - n2->m_len = 0; - memcpy(mtod(n2, caddr_t), - mtod(m, caddr_t) + skip, remain); - n2->m_len = remain; - /* splice in second mbuf */ - n2->m_next = n->m_next; - n->m_next = n2; - V_ipsec4stat.ips_mbinserted++; - } else { - memcpy(mtod(n, caddr_t) + hlen, - mtod(m, caddr_t) + skip, remain); - n->m_len += remain; + if (n0 != NULL) { + *np = m->m_next; + m->m_next = n0; } - m->m_len -= remain; - n->m_len += hlen; + } + else { + n = m_get(M_DONTWAIT, m->m_type); + if (n == NULL) { + m_freem(n0); + return NULL; + } + alloc++; + + if ((n->m_next = n0) == NULL) + np = &n->m_next; + n0 = n; + + *np = m->m_next; + m->m_next = n0; + + n->m_len = hlen; + m->m_len = skip; + m = n; /* header is at front ... */ *off = 0; /* ... of new mbuf */ } + V_ipsec4stat.ips_mbinserted++; } else { /* * Copy the remainder to the back of the mbuf