Subject: Re: m_pulldown()
To: None <tech-net@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 12/02/1999 02:48:08
>> What's wrong with m_pullup()?

> One reason: m_pullup can fail.  And then you lose the packet.

Um.  Right.  (Of course, if it fails you are probably close to resource
exhaustion anyway, but that's not really an excuse.)

> there's no reason why you can't point to existing data, but if you
> can't then m_copydata to a local buffer on the stack.

Suggestion, then: a routine to do that.  Something like this, exact
details of course open to debate:

	void *m_copy_or_point(struct mbuf *m, int len, void *buf);

	If there are at least len bytes in the first mbuf in the chain
	pointed to by m, this returns mtod(m,void *).  Otherwise, it
	copies the first len bytes of the mbuf chain (reading from as
	many mbufs as necessary) into buf, which must be at least len
	bytes long, and then returns buf.  If len is greater than the
	total length of the entire mbuf chain, returns nil (and may or
	may not modify the buffer pointed to by buf).

For the sake of unaligned packets on architectures where alignment
restrictions matter (eg, SPARC but not VAX), it might be good to have

void *m_copy_or_point(struct mbuf *m, int len, void *buf, int alignment)

like the above, except that if mtod(m,void *) is not aligned to a
multiple of alignment, it does the copy anyway.  (I recently coded an
encapsulation interface, and I have three unused padding bytes in every
packet to ensure that the inner packet is 32-bit-aligned; my first
attempt panicked with an alignment fault in the kernel because the
inner IP header was at an odd address.)

I'd *like* to make it try to modify the mbuf chain a la m_pullup, and
fall back to copying if it can't get the resource, but I see with no
good way to return the new mbuf chain - it'd have to bash the existing
chain head structure, which is rather gross and might even break
something if anything does mtod(), saves the pointer, uses m_adj() to
skip the data, passes the mbuf on to something that might do this
pseudo-pullup operation, and then uses the saved data pointer.

					der Mouse

			       mouse@rodents.montreal.qc.ca
		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B