diff options
author | gallatin <gallatin@FreeBSD.org> | 2000-05-26 13:47:02 +0000 |
---|---|---|
committer | gallatin <gallatin@FreeBSD.org> | 2000-05-26 13:47:02 +0000 |
commit | 0eb0bb6777534bbb9dd3aac1d82ae83306648b43 (patch) | |
tree | fd1f2eb8a25c3b4ce9810fa14131cb2c89d41c83 | |
parent | 2a39533c003007b1c26ce9ae8ce4ee9cf5a59884 (diff) | |
download | FreeBSD-src-0eb0bb6777534bbb9dd3aac1d82ae83306648b43.zip FreeBSD-src-0eb0bb6777534bbb9dd3aac1d82ae83306648b43.tar.gz |
Rather than checking for hlen causing misalignment, we should do the
m_adj() and then check the resulting mbuf for misalignment, copying
backwards to align the mbuf if required.
This fixes a longstanding problem where an mbuf which would have been
properly aligned after an m_adj() was being misaligned and causing an
unaligned access trap in ip_input(). This bug only triggered when booting
diskless.
Reviewed by: dfr
-rw-r--r-- | sys/net/if_loop.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 5f6e91b..741e09c 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -242,17 +242,19 @@ if_simloop(ifp, m, af, hlen) /* Strip away media header */ if (hlen > 0) { + m_adj(m, hlen); #ifdef __alpha__ /* The alpha doesn't like unaligned data. * We move data down in the first mbuf */ - if (hlen & 3) { - bcopy(m->m_data + hlen, m->m_data, m->m_len - hlen); - m->m_len -= hlen; - if (m->m_flags & M_PKTHDR) - m->m_pkthdr.len -= hlen; - } else + if (mtod(m, vm_offset_t) & 3) { + KASSERT(hlen >= 3, "if_simloop: hlen too small"); + bcopy(m->m_data, + (char *)(mtod(m, vm_offset_t) + - (mtod(m, vm_offset_t) & 3)), + m->m_len); + mtod(m,vm_offset_t) -= (mtod(m, vm_offset_t) & 3); + } #endif - m_adj(m, hlen); } /* Deliver to upper layer protocol */ |