In most cases etherip encapsulation works but it fails horribly when the
ethernet header added by ether_output was prepended into a new mbuf.
Add "magic" code to fixup the alignment of the packet so that the IP
header starts again on a word boundary.
With this my sparc64 is able to vether -> bridge -> gif again without
crashing. OK?
--
:wq Claudio
Index: ip_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ether.c,v
retrieving revision 1.55
diff -u -p -r1.55 ip_ether.c
--- ip_ether.c 2 Jul 2010 02:40:16 -0000 1.55
+++ ip_ether.c 28 Oct 2010 11:33:08 -0000
@@ -501,6 +501,22 @@ etherip_output(struct mbuf *m, struct td
return ENOBUFS;
}
+#ifdef __STRICT_ALIGNMENT
+ /* buffer must be word aligned because of IP header */
+ if ((long)mtod(m, caddr_t) & 0x03) {
+ /* need to fixup alignment */
+ int off = (long)mtod(m, caddr_t) & 0x03;
+ /* mbuf always start word aligned so there must be room,
+ * we could call M_PREPEND() but doing it by hand causes
+ * less surprises. */
+ if (M_LEADINGSPACE(m) < off)
+ panic("etherip_output: align fixup failed");
+ m->m_data -= off;
+ bcopy(mtod(m, caddr_t) + off, mtod(m, caddr_t), m->m_len);
+ }
+#endif
+
+
/* Statistics */
etheripstat.etherip_opackets++;
etheripstat.etherip_obytes += m->m_pkthdr.len - hlen;