Subject: Re: m_pulldown()
To: None <tech-net@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 12/03/1999 00:09:59
>> The function I'm proposing is:
>> void *m_extract(struct mbuf *m, size_t offset, size_t len, size_t alignment, void *buf);

I'd most certainly support this.

> 	I think m_pulldown() is much simpler on variable-length headers
> 	(IPv6 uses many of them):
> 	- for m_extract how much buffer do we need to pre-allocate is
> 	  not known.

Exactly len bytes.  By the time you call m_extract you must know len;
that's how much space you need.  If you have to allocate it
dynamically, you have to - but when you don't have to, don't.
(Question: of those variable-length headers IPv6 uses, how many would
it be impractical to allocate a max-length buffer on the stack?)

> 	  m_pulldown() does not have the problem (uses mbuf).

Instead, it has another problem: it can fail and lose the packet in the
process.

> 	- m_extract makes copy twice for same region, for variable
> 	  length header.  (you can't avoid it as the copy/non-copy is
> 	  hidden in the funtion)

See below.

> 	- we are not certain if copy is performed or not, so we are not
> 	  sure if we can overwrite it or not (the answer is to use
> 	  m_copydata when we need overwrite, but i imagine people will
> 	  misinterpret it)

We can hardly be responsible for coders misinterpreting the
documentation; if we make the doc (including examples) clear, I can't
work up very much sympathy for people who insist on shooting themselves
in the foot.

> --- m_extract
> 	struct foohdr *f;
> 	f = m_extract(m, off, sizeof(struct foohdr), 8, buf));
> 	if (f->len > sizeof(buf))
> 		panic("bang");
> #if 1
> 	/* makes copy twice on the same region */
> 	m_extract(m, off, f->len, 8, buf);
> #endif
> 	/*
> 	 * you can't do it as you are uncertain if the first m_extract
> 	 * made a copy of not, and if second m_extract makes a copy or not.
> 	 */
> 	m_extract(m, off + sizeof(struct foohdr),
> 		f->len - sizeof(struct foohdr), 8, buf + sizeof(struct foohdr));

Why would you *ever* call m_extract and ignore the return value?  One
of us is missing something big here.

But why do you insist on having the fixed-size and variable-size
portions of foohdr end up contiguous in memory?

					der Mouse

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