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