Module Name: src Committed By: ryo Date: Fri Nov 29 17:29:32 UTC 2019
Modified Files: src/sys/net: bpf.c Log Message: bpf can send a packet greater than MCLBYTES (JumboFrame) using multiple mbuf. To generate a diff of this commit: cvs rdiff -u -r1.231 -r1.232 src/sys/net/bpf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/bpf.c diff -u src/sys/net/bpf.c:1.231 src/sys/net/bpf.c:1.232 --- src/sys/net/bpf.c:1.231 Fri Sep 13 06:39:29 2019 +++ src/sys/net/bpf.c Fri Nov 29 17:29:31 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: bpf.c,v 1.231 2019/09/13 06:39:29 maxv Exp $ */ +/* $NetBSD: bpf.c,v 1.232 2019/11/29 17:29:31 ryo Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.231 2019/09/13 06:39:29 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.232 2019/11/29 17:29:31 ryo Exp $"); #if defined(_KERNEL_OPT) #include "opt_bpf.h" @@ -321,7 +321,7 @@ static int bpf_movein(struct uio *uio, int linktype, uint64_t mtu, struct mbuf **mp, struct sockaddr *sockp) { - struct mbuf *m; + struct mbuf *m, *m0, *n; int error; size_t len; size_t hlen; @@ -395,15 +395,7 @@ bpf_movein(struct uio *uio, int linktype if (len - hlen > mtu) return (EMSGSIZE); - /* - * XXX Avoid complicated buffer chaining --- - * bail if it won't fit in a single mbuf. - * (Take into account possible alignment bytes) - */ - if (len + align > MCLBYTES) - return (EIO); - - m = m_gethdr(M_WAIT, MT_DATA); + m0 = m = m_gethdr(M_WAIT, MT_DATA); m_reset_rcvif(m); m->m_pkthdr.len = (int)(len - hlen); if (len + align > MHLEN) { @@ -415,25 +407,39 @@ bpf_movein(struct uio *uio, int linktype } /* Insure the data is properly aligned */ - if (align > 0) { + if (align > 0) m->m_data += align; - m->m_len -= (int)align; + + for (;;) { + len = M_TRAILINGSPACE(m); + if (len > uio->uio_resid) + len = uio->uio_resid; + error = uiomove(mtod(m, void *), len, uio); + if (error) + goto bad; + m->m_len = len; + + if (uio->uio_resid == 0) + break; + + n = m_get(M_WAIT, MT_DATA); + m_clget(n, M_WAIT); /* if fails, there is no problem */ + m->m_next = n; + m = n; } - error = uiomove(mtod(m, void *), len, uio); - if (error) - goto bad; if (hlen != 0) { - memcpy(sockp->sa_data, mtod(m, void *), hlen); - m->m_data += hlen; /* XXX */ - len -= hlen; + /* move link level header in the top of mbuf to sa_data */ + memcpy(sockp->sa_data, mtod(m0, void *), hlen); + m0->m_data += hlen; + m0->m_len -= hlen; } - m->m_len = (int)len; - *mp = m; + + *mp = m0; return (0); bad: - m_freem(m); + m_freem(m0); return (error); }