From owner-freebsd-net@FreeBSD.ORG Tue Jun 5 18:13:17 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D79CC1065672 for ; Tue, 5 Jun 2012 18:13:17 +0000 (UTC) (envelope-from darrenr@freebsd.org) Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) by mx1.freebsd.org (Postfix) with ESMTP id A37BE8FC15 for ; Tue, 5 Jun 2012 18:13:17 +0000 (UTC) Received: from compute2.internal (compute2.nyi.mail.srv.osa [10.202.2.42]) by gateway1.nyi.mail.srv.osa (Postfix) with ESMTP id A52EB2108B for ; Tue, 5 Jun 2012 14:13:11 -0400 (EDT) Received: from frontend1.nyi.mail.srv.osa ([10.202.2.160]) by compute2.internal (MEProxy); Tue, 05 Jun 2012 14:13:11 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=message-id:date:from:reply-to :mime-version:to:subject:content-type:content-transfer-encoding; s=smtpout; bh=QoRjX2tCwKb+9AnwrwW7L8/6uCA=; b=kUe7L/8KbJf2FUXTK n/63vBvtpWiRwmH5MHbvRpyAmdBJHTrOb4LgPV6on9piFTW11135ng4wuLeXfYmp oAu0A/HvWjLhSbGiAuXHhKuwSbhbvVd75Kvt+gdLGGBTPQgEblgoSjpWZk5uLWhJ QFigrzEvJi4tZnyHH7T8j4mNao= X-Sasl-enc: 3nb4lS+OZ02iQ+Sq66hn8F1FanKGfERWu8qZEjP7lqmO 1338919991 Received: from [192.168.1.124] (unknown [202.45.110.141]) by mail.messagingengine.com (Postfix) with ESMTPA id EC2638E0187 for ; Tue, 5 Jun 2012 14:13:10 -0400 (EDT) Message-ID: <4FCE4CAB.1080802@freebsd.org> Date: Wed, 06 Jun 2012 04:15:07 +1000 From: Darren Reed Organization: FreeBSD User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20120428 Thunderbird/12.0.1 MIME-Version: 1.0 To: freebsd-net@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: kern/168190: [pf] panic when using pf and route-to (maybe: bad fragment handling?) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: darrenr@freebsd.org List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jun 2012 18:13:18 -0000 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 */