Discussion:
mbuf and IP frame lengths
(too old to reply)
Alan Garfield
2007-04-16 07:14:06 UTC
Permalink
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
bcopy(buf + 1, (char *)eh, FIFO_SIZE - 1);

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

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 interface is working just fine, but I'm not sure if I'm completely
correct in the way I'm doing this.

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).

Any help would be greatly appreciated.

Thanks,
Alan.
Yar Tikhiy
2007-04-18 06:47:20 UTC
Permalink
Post by Alan Garfield
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.
Post by Alan Garfield
bcopy(buf + 1, (char *)eh, FIFO_SIZE - 1);
See below.
Post by Alan Garfield
// Set the header length
m->m_pkthdr.len = m->m_len = FIFO_SIZE - 1;
Ditto.
Post by Alan Garfield
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)
Post by Alan Garfield
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.
Post by Alan Garfield
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
Loading...