tun(4)/tap(4) function tun_dev_write() is checking for the wrong size for
the mbuf packet header. We must check against MHLEN (the mbuf header data
storage size) and not MINCLSIZE (smallest amount of data of a cluster).
For the curious:
MGETHDR() calls m_gethdr() which uses mbpool to get the mbuf data
storage. mbpool is initialized at mbinit() which sets the members
allocation size to MSIZE.
- MSIZE is "256";
- MLEN is "(MSIZE - sizeof(struct m_hdr))"
- MHLEN is "(MLEN - sizeof(pkthdr))";
- MINCLSIZE is "MHLEN + MLEN + 1";
ok?
Index: sys/net/if_tun.c
===================================================================
RCS file: /home/obsdcvs/src/sys/net/if_tun.c,v
retrieving revision 1.169
diff -u -p -r1.169 if_tun.c
--- sys/net/if_tun.c 4 Sep 2016 15:46:39 -0000 1.169
+++ sys/net/if_tun.c 24 Oct 2016 07:43:03 -0000
@@ -895,7 +895,7 @@ tun_dev_write(struct tun_softc *tp, stru
if (m == NULL)
return (ENOBUFS);
mlen = MHLEN;
- if (uio->uio_resid >= MINCLSIZE) {
+ if (uio->uio_resid >= MHLEN) {
MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
m_free(m);
@@ -926,7 +926,7 @@ tun_dev_write(struct tun_softc *tp, stru
break;
}
mlen = MLEN;
- if (uio->uio_resid >= MINCLSIZE) {
+ if (uio->uio_resid >= MHLEN) {
MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
error = ENOBUFS;