Subject: Re: Patch to make upper-layer network protocols align as needed
To: None <thorpej@wasabisystems.com>
From: None <itojun@iijlab.net>
List: tech-net
Date: 05/22/2002 16:06:11
> > the "side-effect" will happen only if m_pullup() is called, or
> > m_pulldown() is called with off == 0 (2nd arg). i guess we need
> > some check in IP6_EXTHDR_GET() macro.
>Can you cook something up for this?
sorry for the delay, how about this?
not sure if ALIGN() is the correct way to detect unalignedness.
testers wanted, with align-picky archs (i have i386 only).
itojun
Index: kern/uipc_mbuf2.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/uipc_mbuf2.c,v
retrieving revision 1.9
diff -u -r1.9 uipc_mbuf2.c
--- kern/uipc_mbuf2.c 2002/04/28 00:53:34 1.9
+++ kern/uipc_mbuf2.c 2002/05/22 07:02:12
@@ -74,6 +74,8 @@
#include <sys/malloc.h>
#include <sys/mbuf.h>
+#define ALIGNED(x) ((u_long)(x) == ALIGN((x)))
+
/*
* ensure that [off, off + len) is contiguous on the mbuf chain "m".
* packet chain before "off" is kept untouched.
@@ -120,6 +122,12 @@
sharedcluster = M_READONLY(n);
/*
+ * if unaligned, do it in a hard way
+ */
+ if (!ALIGNED(mtod(n, caddr_t) + off))
+ goto unaligned;
+
+ /*
* the target data is on <n, off>.
* if we got enough data on the mbuf "n", we're done.
*/
@@ -146,6 +154,7 @@
goto ok;
}
+unaligned:
/*
* we need to take hlen from <n, off> and tlen from <n->m_next, 0>,
* and construct contiguous mbuf with m_len == len.
@@ -171,6 +180,7 @@
* we need to use m_copydata() to get data from <n->m_next, 0>.
*/
if ((off == 0 || offp) && M_TRAILINGSPACE(n) >= tlen &&
+ ALIGNED(mtod(n, caddr_t) + n->m_len) &&
!sharedcluster) {
m_copydata(n->m_next, 0, tlen, mtod(n, caddr_t) + n->m_len);
n->m_len += tlen;
@@ -178,6 +188,7 @@
goto ok;
}
if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen &&
+ ALIGNED(mtod(n->m_next, caddr_t) - hlen) &&
!sharedcluster) {
n->m_next->m_data -= hlen;
n->m_next->m_len += hlen;
Index: netinet/ip6.h
===================================================================
RCS file: /cvsroot/syssrc/sys/netinet/ip6.h,v
retrieving revision 1.12
diff -u -r1.12 ip6.h
--- netinet/ip6.h 2001/07/05 23:41:07 1.12
+++ netinet/ip6.h 2002/05/22 07:02:14
@@ -261,7 +261,8 @@
do { \
struct mbuf *t; \
int tmp; \
- if ((m)->m_len >= (off) + (len)) \
+ if ((m)->m_len >= (off) + (len) && \
+ (u_long)mtod((m), caddr_t) + off == ALIGN(mtod((m), caddr_t) + off)) \
(val) = (typ)(mtod((m), caddr_t) + (off)); \
else { \
t = m_pulldown((m), (off), (len), &tmp); \
@@ -279,7 +280,8 @@
#define IP6_EXTHDR_GET0(val, typ, m, off, len) \
do { \
struct mbuf *t; \
- if ((off) == 0 && (m)->m_len >= len) \
+ if ((off) == 0 && (m)->m_len >= len && \
+ (u_long)mtod((m), caddr_t) == ALIGN(mtod((m), caddr_t))) \
(val) = (typ)mtod((m), caddr_t); \
else { \
t = m_pulldown((m), (off), (len), NULL); \