BPF packet pagesize limit
Kristof Provost
kristof at sigsegv.be
Mon Nov 20 21:26:19 UTC 2017
On 19 Nov 2017, at 19:49, Catalin Salgau wrote:
> I'm trying to address the limitation in (upstream) net/vblade that was
> brought up in
> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=205164
> This is related to writes larger than hw.pagesize but smaller than the
> configured MTU with BPF.
> I traced this to sys/net/bpf.c where calls to bpfwrite() will use
> bpf_movein() which in turn uses m_get2() to allocate a single mbuf.
> This
> will fail if the requested mbuf size is larger than MJUMPAGESIZE
> (defined as PAGE_SIZE on x86). I believe this should use m_getm2() and
> populate multiple mbufs.
> Code in NetBSD explicitly notes that they omit mbuf chaining, but this
> is not documentated behaviour in the man page.
>
Your analysis looks correct.
> Any chance of having this fixed in a supported release, or getting a
> usable/documented workaround?
Can you see if this works for you?
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index b176856cf35..b9ff40699bb 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -547,9 +547,11 @@ bpf_movein(struct uio *uio, int linktype, struct
ifnet *ifp, struct mbuf **mp,
if (len < hlen || len - hlen > ifp->if_mtu)
return (EMSGSIZE);
- m = m_get2(len, M_WAITOK, MT_DATA, M_PKTHDR);
+ m = m_getm2(NULL, len, M_WAITOK, MT_DATA, M_PKTHDR);
if (m == NULL)
return (EIO);
+ KASSERT(m->m_next == NULL, ("mbuf chains not supported here"));
+
m->m_pkthdr.len = m->m_len = len;
*mp = m;
It’s a little icky to trust that this will produce a single mbuf
rather than a chain, but it appears to be the case. Sadly the rest of
the bpf code (and especially bpf_filter()) really needs the mbuf to have
a single contiguous buffer.
Regards,
Kristof
More information about the freebsd-net
mailing list