From b09db08f24802a7064b4bc3073d6dd77af6e6424 Mon Sep 17 00:00:00 2001 From: silby Date: Wed, 28 May 2003 02:04:33 +0000 Subject: Replace a handrolled defrag function with m_defrag. The handrolled function couldn't handle chains of > MCLBYTES, and it had a bug which caused corruption and panics in certain low mbuf situations. Additionally, change the failure case so that looutput returns ENOBUFS rather than attempting to pass on non-defragmented mbuf chains. Finally, remove the printf which would happen every time the low memory situation occured. It served no useful purpose other than to clue me in as to what was causing the panic in question. :) MFC after: 4 days --- sys/net/if_loop.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) (limited to 'sys/net') diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index b78b146..7158b3d 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -192,6 +192,7 @@ looutput(ifp, m, dst, rt) struct sockaddr *dst; register struct rtentry *rt; { + struct mbuf *n; M_ASSERTPKTHDR(m); /* check if we have the packet header */ @@ -204,30 +205,22 @@ looutput(ifp, m, dst, rt) * KAME requires that the packet to be contiguous on the * mbuf. We need to make that sure. * this kind of code should be avoided. - * XXX: fails to join if interface MTU > MCLBYTES. jumbogram? + * + * XXX: KAME may no longer need contiguous packets. Once + * that has been verified, the following code _should_ be + * removed. */ - if (m && m->m_next != NULL && m->m_pkthdr.len < MCLBYTES) { - struct mbuf *n; - - /* XXX MT_HEADER should be m->m_type */ - MGETHDR(n, M_DONTWAIT, MT_HEADER); - if (!n) - goto contiguousfail; - M_MOVE_PKTHDR(n, m); - MCLGET(n, M_DONTWAIT); - if (! (n->m_flags & M_EXT)) { - m_freem(n); - goto contiguousfail; - } - m_copydata(m, 0, n->m_pkthdr.len, mtod(n, caddr_t)); - n->m_len = n->m_pkthdr.len; - m_freem(m); - m = n; - } - if (0) { -contiguousfail: - printf("looutput: mbuf allocation failed\n"); + if (m && m->m_next != NULL) { + + n = m_defrag(m, M_DONTWAIT); + + if (n == NULL) { + m_freem(m); + return (ENOBUFS); + } else { + m = n; + } } ifp->if_opackets++; -- cgit v1.1