Subject: Re: unaligned IP header
To: None <>
From: Darren Reed <>
List: tech-net
Date: 04/24/2000 22:32:51
In some email I received from Jason R Thorpe, sie wrote:
> On Mon, Apr 24, 2000 at 11:23:45AM +0900, wrote:
>  > 	are you suggesting something like this in ip_input()?
>  > 
>  > itojun
>  > 
>  > 
>  > if (((u_long)mtod(m, caddr_t)) % ALIGNBYTES) {
>  > 	/* unaligned ip header - force pullup */
>  > 	m = m_pullup_always(m, sizeof struct ip);	/*always pullup*/
>  > }
> Well, the exact clause would be more like:
> 	if (ALIGNED_POINTER(mtod(m, caddr_t), u_int32_t) == 0) {
> 		/* Unaligned IP header -- force pullup */
> 		m = m_pullup_always(m, sizeof(struct ip));
> 	}
> ....but this requires additional memory allocation, and additional data
> copying.
> Now, we could eliminate the memory allocation part by doing the m_extract()
> thing suggested by Matt Thomas previously (during the m_pulldown()
> discussion), and by passing a "struct ip_info" around.

Aligning the packet is a much better option.  If IP header fields are
unaligned then so will TCP header fields, so if you have an "ip_info"
thing, then all of a sudden you need either a "tcp_info" thing too or
to put TCP information into it.

Now...since the IP header is starting on an unaligned boundary and we
know that the buffer space for the data in an mbuf starts on an aligned
address (right ? :) all we *really* want to do is move the packet.  A
call to memmove or bcopy should be all that's required, with no real
need to allocate a new mbuf.  We only *need* to move data in the first
mbuf, so it should be of little significance really.  I'll leave the
actual code as an exercise for the reader.