svn commit: r189997 - in stable/6/sys: . contrib/pf dev/cxgb net netinet netinet6

Marius Strobl marius at FreeBSD.org
Wed Mar 18 15:13:32 PDT 2009


Author: marius
Date: Wed Mar 18 22:13:29 2009
New Revision: 189997
URL: http://svn.freebsd.org/changeset/base/189997

Log:
  MFC: r189494
  
  On architectures with strict alignment requirements compensate
  the misalignment of the IP header that prepending the EtherIP
  header might have caused.
  
  PR:		131921

Modified:
  stable/6/sys/   (props changed)
  stable/6/sys/contrib/pf/   (props changed)
  stable/6/sys/dev/cxgb/   (props changed)
  stable/6/sys/net/if_gif.h
  stable/6/sys/netinet/in_gif.c
  stable/6/sys/netinet6/in6_gif.c

Modified: stable/6/sys/net/if_gif.h
==============================================================================
--- stable/6/sys/net/if_gif.h	Wed Mar 18 22:12:54 2009	(r189996)
+++ stable/6/sys/net/if_gif.h	Wed Mar 18 22:13:29 2009	(r189997)
@@ -99,6 +99,8 @@ struct etherip_header {
 #define ETHERIP_VER_VERS_MASK   0x0f
 #define ETHERIP_VER_RSVD_MASK   0xf0
 #define ETHERIP_VERSION         0x03
+/* mbuf adjust factor to force 32-bit alignment of IP header */
+#define	ETHERIP_ALIGN		2
 
 /* Prototypes */
 void gif_input(struct mbuf *, int, struct ifnet *);

Modified: stable/6/sys/netinet/in_gif.c
==============================================================================
--- stable/6/sys/netinet/in_gif.c	Wed Mar 18 22:12:54 2009	(r189996)
+++ stable/6/sys/netinet/in_gif.c	Wed Mar 18 22:13:29 2009	(r189997)
@@ -101,7 +101,7 @@ in_gif_output(ifp, family, 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);
@@ -185,13 +185,27 @@ in_gif_output(ifp, family, 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));
 
 	if (dst->sin_family != sin_dst->sin_family ||

Modified: stable/6/sys/netinet6/in6_gif.c
==============================================================================
--- stable/6/sys/netinet6/in6_gif.c	Wed Mar 18 22:12:54 2009	(r189996)
+++ stable/6/sys/netinet6/in6_gif.c	Wed Mar 18 22:13:29 2009	(r189997)
@@ -96,7 +96,7 @@ in6_gif_output(ifp, family, m)
 	struct sockaddr_in6 *sin6_dst = (struct sockaddr_in6 *)sc->gif_pdst;
 	struct ip6_hdr *ip6;
 	struct etherip_header eiphdr;
-	int proto, error;
+	int error, len, proto;
 	u_int8_t itos, otos;
 
 	GIF_LOCK_ASSERT(sc);
@@ -164,13 +164,27 @@ in6_gif_output(ifp, family, m)
 	}
 
 	/* prepend new IP header */
-	M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
-	if (m && m->m_len < sizeof(struct ip6_hdr))
-		m = m_pullup(m, sizeof(struct ip6_hdr));
+	len = sizeof(struct ip6_hdr);
+#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 in6_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,
+		    ("in6_gif_output: unexpected misalignment"));
+		m->m_data += len;
+		m->m_len -= ETHERIP_ALIGN;
+	}
+#endif
 
 	ip6 = mtod(m, struct ip6_hdr *);
 	ip6->ip6_flow	= 0;


More information about the svn-src-all mailing list