Minor hack in the netgraph interface to ethernets.

This commit is contained in:
Julian Elischer 1999-10-26 11:40:23 +00:00
parent cfbcfe6272
commit 021823c35c

View File

@ -1133,29 +1133,78 @@ bad:
/*
* pass an mbuf out to the connected hook
*/
* More complicated than just an m_prepend, as it tries to save later nodes
* from needing to do lots of m_pullups.
*/
static void
ngether_send(struct arpcom *ac, struct ether_header *eh, struct mbuf *m)
{
{
int room;
node_p node = AC2NG(ac);
struct ether_header *eh2;
if (node && LIST_FIRST(&(node->hooks))) {
M_PREPEND(m, sizeof(*eh), M_DONTWAIT);
if (m == 0)
return;
eh2 = mtod(m, struct ether_header *);
/*
* Possibly 'eh' already points
* to the right place.
* Possibly the header is already on the front,
*/
if (eh2 != eh)
bcopy(eh, eh2, sizeof(*eh));
eh2 = mtod(m, struct ether_header *) - 1;
if ( eh == eh2) {
/*
* This is the case so just move the markers back to
* re-include it. We lucked out.
* This allows us to avoid a yucky m_pullup
* in later nodes if it works.
*/
m->m_len += sizeof(*eh);
m->m_data -= sizeof(*eh);
m->m_pkthdr.len += sizeof(*eh);
} else {
/*
* Alternatively there may be room even though
* it is stored somewhere else. If so, copy it in.
* This only safe because we KNOW that this packet has
* just been generated by an ethernet card, so there
* are no aliases to the buffer. (unlike in outgoing
* packets).
* Nearly all ethernet cards will end up producing mbufs
* that fall into these cases. So we are not optimising
* contorted cases.
*/
if (m->m_flags & M_EXT) {
room = (mtod(m, caddr_t) - m->m_ext.ext_buf);
if (room > m->m_ext.ext_size) /* garbage */
room = 0; /* fail immediatly */
} else {
room = (mtod(m, caddr_t) - m->m_pktdat);
}
if (room > sizeof (*eh)) {
/* we have room, just copy it and adjust */
m->m_len += sizeof(*eh);
m->m_data -= sizeof(*eh);
m->m_pkthdr.len += sizeof(*eh);
bcopy ((caddr_t)eh, (caddr_t)eh2, sizeof(*eh));
} else {
/*
* Doing anything more is likely to get more
* expensive than it's worth..
* it's probable that everything else is in one
* big lump. The next node will do an m_pullup()
* for exactly the amount of data it needs and
* hopefully everything after that will not
* need one. So let's just use m_prepend.
*/
m = m_prepend(m, MHLEN, M_DONTWAIT);
if (m == NULL)
return;
}
}
ng_queue_data(LIST_FIRST(&(node->hooks)), m, NULL);
} else {
m_freem(m);
}
}
/*
* do local shutdown processing..
* This node will refuse to go away, unless the hardware says to..