summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2009-03-07 19:08:58 +0000
committermarius <marius@FreeBSD.org>2009-03-07 19:08:58 +0000
commit74f63d4ce14b7d970f6fe45d8d855faaaf5f7ed5 (patch)
tree25a76694bea3791d223804b5dab3dae47761145d /sys/netinet
parent09f1ec373e0d13417810ac3620b458cf50cd65d7 (diff)
downloadFreeBSD-src-74f63d4ce14b7d970f6fe45d8d855faaaf5f7ed5.zip
FreeBSD-src-74f63d4ce14b7d970f6fe45d8d855faaaf5f7ed5.tar.gz
On architectures with strict alignment requirements compensate
the misalignment of the IP header that prepending the EtherIP header might have caused. PR: 131921 MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_gif.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index 9bcb09e..a05c04b 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -102,7 +102,7 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
struct sockaddr_in *sin_dst = (struct sockaddr_in *)sc->gif_pdst;
struct ip iphdr; /* capsule IP header, host byte ordered */
struct etherip_header eiphdr;
- int proto, error;
+ int error, len, proto;
u_int8_t tos;
GIF_LOCK_ASSERT(sc);
@@ -186,13 +186,27 @@ in_gif_output(struct ifnet *ifp, int family, struct mbuf *m)
&iphdr.ip_tos, &tos);
/* prepend new IP header */
- M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
- if (m && m->m_len < sizeof(struct ip))
- m = m_pullup(m, sizeof(struct ip));
+ len = sizeof(struct ip);
+#ifndef __NO_STRICT_ALIGNMENT
+ if (family == AF_LINK)
+ len += ETHERIP_ALIGN;
+#endif
+ M_PREPEND(m, len, M_DONTWAIT);
+ if (m != NULL && m->m_len < len)
+ m = m_pullup(m, len);
if (m == NULL) {
printf("ENOBUFS in in_gif_output %d\n", __LINE__);
return ENOBUFS;
}
+#ifndef __NO_STRICT_ALIGNMENT
+ if (family == AF_LINK) {
+ len = mtod(m, vm_offset_t) & 3;
+ KASSERT(len == 0 || len == ETHERIP_ALIGN,
+ ("in_gif_output: unexpected misalignment"));
+ m->m_data += len;
+ m->m_len -= ETHERIP_ALIGN;
+ }
+#endif
bcopy(&iphdr, mtod(m, struct ip *), sizeof(struct ip));
M_SETFIB(m, sc->gif_fibnum);
OpenPOWER on IntegriCloud