mbuf and IP frame lengths

Yar Tikhiy yar at comp.chem.msu.su
Wed Apr 18 06:47:25 UTC 2007


On Mon, Apr 16, 2007 at 05:14:06PM +1000, Alan Garfield wrote:
> Hi all!
> 
> A question, is it ok to just say pass an entire rx buffer of your
> ethernet device up the chain and let the ip stack figure out the frame
> size.
> 
> I have a device that can only ever receive 255 bytes of data, I receive
> this data from a buffer in the PRS. On an interrupt I read this data out
> of the PRS buffer into a local buffer, which I then :-
> 
> ----
>         eh = mtod(m, struct ether_header *);
> 
>         // Copy buf into mbuf

Please use plain C comments for the sake of style(9) if you
want your driver to be a good example.

>         bcopy(buf + 1, (char *)eh, FIFO_SIZE - 1);

See below.

> 
>         // Set the header length 
>         m->m_pkthdr.len = m->m_len = FIFO_SIZE - 1;

Ditto.

>         JNET_UNLOCK(sc);
>         (*ifp->if_input)(ifp, m);
>         JNET_LOCK(sc);
> ----
> 
> FIFO_SIZE = 256, minus 1 for a control character in the device (which
> handily keeps under the 256 frame size).

The constant 1 there is worth a symbolic name.  E.g.:

/* The offset of an actual Ethernet frame into the FIFO */
#define	FRAME_OFFSET	1
/* XXX is frame size fixed? */
#define FRAME_SIZE	(FIFO_SIZE - FRAME_OFFSET)

> The interface is working just fine, but I'm not sure if I'm completely
> correct in the way I'm doing this.

AFAIK it's OK to pass a longer mbuf chain.  E.g., real Ethernet has
a limit on minimum frame size, which is 46 bytes of payload plus a
header and an FCS, and Ethernet II encapsulation doesn't specify
payload size; but it doesn't mean that you can't send an IPv4 packet
with less than 26 bytes of IP payload over Ethernet.

My only reservation is that less data could be copied from the
device memory if the driver knew the actual frame size, but your
device might have no such notion at all, relying on the upper layer,
such as IP, to specify accurate data size.

> I've tried casting the buffer to struct ip* to get ip->ip_len but I
> always get a "dereferencing pointer to incomplete type" error (don't
> exactly know why).

Perhaps it's because your driver doesn't include all IP related
headers.  But in fact it shouldn't try to analyze IP headers because
that isn't its job.

-- 
Yar


More information about the freebsd-hackers mailing list