summaryrefslogtreecommitdiffstats
path: root/sys/net/if_loop.c
diff options
context:
space:
mode:
authorgallatin <gallatin@FreeBSD.org>2000-05-26 13:47:02 +0000
committergallatin <gallatin@FreeBSD.org>2000-05-26 13:47:02 +0000
commit0eb0bb6777534bbb9dd3aac1d82ae83306648b43 (patch)
treefd1f2eb8a25c3b4ce9810fa14131cb2c89d41c83 /sys/net/if_loop.c
parent2a39533c003007b1c26ce9ae8ce4ee9cf5a59884 (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/net/if_loop.c')
-rw-r--r--sys/net/if_loop.c16
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 */
OpenPOWER on IntegriCloud