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);
}