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;

Reply via email to