Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 06 Jun 2012 04:15:07 +1000
From:      Darren Reed <darrenr@freebsd.org>
To:        freebsd-net@freebsd.org
Subject:   Re: kern/168190: [pf] panic when using pf and route-to (maybe: bad fragment handling?)
Message-ID:  <4FCE4CAB.1080802@freebsd.org>

next in thread | raw e-mail | index | archive | help
To echo comments made on tech-net for NetBSD...

---
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 FreeBSD (includes IPv6 code.)

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.
---

But otherwise, the root cause of this problem is not solved with this
patch. It's just a workaround.

Darren

*** ip_fil_freebsd.c.orig    26 Jan 2012 06:03:43 -0000
--- ip_fil_freebsd.c    5 Jun 2012 18:09:25 -0000
***************
*** 171,177 ****
  fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
  {
        struct ip *ip = mtod(*mp, struct ip *);
!       return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp);
  }

  # ifdef USE_INET6
--- 171,186 ----
  fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
  {
        struct ip *ip = mtod(*mp, struct ip *);
!       int hlen = ip->ip_hl << 2;
!       struct mbuf *m;
!       int rv;
!
!       rv = fr_check(ip, hlen, ifp, (dir == PFIL_OUT), mp);
!       if ((rv == 0) && ((m = *mp) != NULL)) {
!               if (m->m_len < hlen)
!                       *mp = m_pullup(m, hlen);
!       }
!       return rv;
  }

  # ifdef USE_INET6
***************
*** 180,187 ****
  static int
  fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
  {
!       return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr),
!           ifp, (dir == PFIL_OUT), mp));
  }
  # endif
  #endif /* __FreeBSD_version >= 501108 */
--- 189,204 ----
  static int
  fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir)
  {
!       struct mbuf *m;
!       int rv;
!
!       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
  #endif /* __FreeBSD_version >= 501108 */





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4FCE4CAB.1080802>