summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_mbuf.c
diff options
context:
space:
mode:
authorbmilekic <bmilekic@FreeBSD.org>2001-06-20 19:48:35 +0000
committerbmilekic <bmilekic@FreeBSD.org>2001-06-20 19:48:35 +0000
commit70d52016a3f34e35b033755b95ddad49e5f4c50c (patch)
treee79557908ee2eeed9a40c65a32399eb17abca830 /sys/kern/uipc_mbuf.c
parent398c0c0ca03faf96198e155dba0becba4e90d8da (diff)
downloadFreeBSD-src-70d52016a3f34e35b033755b95ddad49e5f4c50c.zip
FreeBSD-src-70d52016a3f34e35b033755b95ddad49e5f4c50c.tar.gz
Change m_devget()'s outdated and unused `offset' argument to actually mean
something: offset into the first mbuf of the target chain before copying the source data over. Make drivers using m_devget() with a first argument "data - ETHER_ALIGN" to use the offset argument to pass ETHER_ALIGN in. The way it was previously done is potentially dangerous if the source data was at the top of a page and the offset caused the previous page to be copied (if the previous page has not yet been appropriately mapped). The old `offset' argument in m_devget() is not used anywhere (it's always 0) and dates back to ~1995 (and earlier?) when support for ethernet trailers existed. With that support gone, it was merely collecting dust. Tested on alpha by: jlemon Partially submitted by: jlemon Reviewed by: jlemon MFC after: 3 weeks
Diffstat (limited to 'sys/kern/uipc_mbuf.c')
-rw-r--r--sys/kern/uipc_mbuf.c55
1 files changed, 25 insertions, 30 deletions
diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index 4134623..a4d3674 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1078,29 +1078,26 @@ extpacket:
}
/*
* Routine to copy from device local memory into mbufs.
+ * Note that `off' argument is offset into first mbuf of target chain from
+ * which to begin copying the data to.
*/
struct mbuf *
-m_devget(char *buf, int totlen, int off0, struct ifnet *ifp,
+m_devget(char *buf, int totlen, int off, struct ifnet *ifp,
void (*copy)(char *from, caddr_t to, u_int len))
{
struct mbuf *m;
struct mbuf *top = 0, **mp = &top;
- int off = off0, len;
- char *cp;
- char *epkt;
-
- cp = buf;
- epkt = cp + totlen;
- if (off) {
- cp += off + 2 * sizeof(u_short);
- totlen -= 2 * sizeof(u_short);
- }
+ int len;
+
+ if (off < 0 || off > MHLEN)
+ return (NULL);
+
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == NULL)
return (NULL);
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = totlen;
- m->m_len = MHLEN;
+ len = MHLEN;
while (totlen > 0) {
if (top) {
@@ -1109,37 +1106,35 @@ m_devget(char *buf, int totlen, int off0, struct ifnet *ifp,
m_freem(top);
return (NULL);
}
- m->m_len = MLEN;
+ len = MLEN;
}
- len = min(totlen, epkt - cp);
- if (len >= MINCLSIZE) {
+ if (totlen + off >= MINCLSIZE) {
MCLGET(m, M_DONTWAIT);
if (m->m_flags & M_EXT)
- m->m_len = len = min(len, MCLBYTES);
- else
- len = m->m_len;
+ len = MCLBYTES;
} else {
/*
* Place initial small packet/header at end of mbuf.
*/
- if (len < m->m_len) {
- if (top == NULL && len +
- max_linkhdr <= m->m_len)
- m->m_data += max_linkhdr;
- m->m_len = len;
- } else
- len = m->m_len;
+ if (top == NULL && totlen + off + max_linkhdr <= len) {
+ m->m_data += max_linkhdr;
+ len -= max_linkhdr;
+ }
+ }
+ if (off) {
+ m->m_data += off;
+ len -= off;
+ off = 0;
}
+ m->m_len = len = min(totlen, len);
if (copy)
- copy(cp, mtod(m, caddr_t), (unsigned)len);
+ copy(buf, mtod(m, caddr_t), (unsigned)len);
else
- bcopy(cp, mtod(m, caddr_t), (unsigned)len);
- cp += len;
+ bcopy(buf, mtod(m, caddr_t), (unsigned)len);
+ buf += len;
*mp = m;
mp = &m->m_next;
totlen -= len;
- if (cp == epkt)
- cp = buf;
}
return (top);
}
OpenPOWER on IntegriCloud