Discussion:
m_copym() panics possibly due to pfil hook?
(too old to reply)
Daniel Hartmeier
2012-06-05 09:05:29 UTC
Permalink
Does someone still experience infrequent m_copym panics, like PR #41588?

This might be related to the pfil hooks and mbufs that don't start with
a contiguous IP header.

If so, see http://marc.info/?l=freebsd-net&m=133888532814565 for an
explanation and simple patch to try.

Kind regards,
Daniel

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Darren Reed
2012-06-05 17:33:50 UTC
Permalink
Post by Daniel Hartmeier
Does someone still experience infrequent m_copym panics, like PR #41588?
This might be related to the pfil hooks and mbufs that don't start with
a contiguous IP header.
If so, see http://marc.info/?l=freebsd-net&m=133888532814565 for an
explanation and simple patch to try.
Kind regards,
Daniel
As much as I dislike the patch you created, I can't see any other way
to elegantly solve the problem. The reason that I don't like the change
is that it seems silly to have to put the packet in two different mbufs
after having put it all in one. I'll file this as a workaround for the
code in m_pulldown() being buggy.

The patch below should work for NetBSD.

The greater problem that I see here is what if someone else were to use
m_pulldown in their home-brew code that uses pfil ... from that angle,
there should be a responsibility to make the interfaces more robust but
perhaps that can be achieved with documentation updates.

Darren

*** ip_fil_netbsd.c.orig 26 Jan 2012 06:03:43 -0000 2.55.2.71
--- ip_fil_netbsd.c 5 Jun 2012 12:14:47 -0000
***************
*** 222,230 ****
rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);

if (rv == 0 && *mp != NULL) {
! ip = mtod(*mp, struct ip *);
! HTONS(ip->ip_len);
! HTONS(ip->ip_off);
}

return (rv);
--- 222,238 ----
rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);

if (rv == 0 && *mp != NULL) {
! struct mbuf *m = *mp;
!
! if (m->m_len < hlen) {
! m = m_pullup(m, hlen);
! *mp = m;
! if (m != NULL) {
! ip = mtod(m, struct ip *);
! HTONS(ip->ip_len);
! HTONS(ip->ip_off);
! }
! }
}

return (rv);

--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Darren Reed
2012-06-05 18:08:06 UTC
Permalink
Scratch that prior patch, it doesn't fix the problem for IPv6.

Darren

*** ip_fil_netbsd.c.orig 26 Jan 2012 06:03:43 -0000 2.55.2.71
--- ip_fil_netbsd.c 5 Jun 2012 18:02:12 -0000
***************
*** 170,175 ****
--- 170,176 ----
struct ifnet *ifp;
int dir;
{
+ struct mbuf *m;
struct ip *ip;
int rv, hlen;

***************
*** 220,230 ****
NTOHS(ip->ip_off);

rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
!
! if (rv == 0 && *mp != NULL) {
! ip = mtod(*mp, struct ip *);
! HTONS(ip->ip_len);
! HTONS(ip->ip_off);
}

return (rv);
--- 221,236 ----
NTOHS(ip->ip_off);

rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
! if ((rv == 0) && ((m = *mp) != NULL)) {
! if (m->m_len < hlen) {
! m = m_pullup(m, hlen);
! *mp = m;
! if (m != NULL) {
! ip = mtod(m, struct ip *);
! HTONS(ip->ip_len);
! HTONS(ip->ip_off);
! }
! }
}

return (rv);
***************
*** 241,246 ****
--- 247,255 ----
struct ifnet *ifp;
int dir;
{
+ struct mbuf *m;
+ int rv;
+
# if defined(M_CSUM_TCPv6) && (__NetBSD_Version__ > 200000000)
/*
* If the packet is out-bound, we can't delay checksums
***************
*** 258,265 ****
}
# endif

! return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
ifp, (dir == PFIL_OUT), mp));
}
# endif

--- 267,279 ----
}
# endif

! rv = fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
ifp, (dir == PFIL_OUT), mp));
+ if ((rv == 0) && ((m = *mp) != NULL)) {
+ if (m->m_len < sizeof(struct ip6_hdr))
+ *mp = m_pullup(m, sizeof(struct ip6_hdr));
+ }
+ return rv;
}
# endif


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...