From owner-freebsd-net@FreeBSD.ORG Sat Mar 14 02:05:07 2015 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3B196AB0; Sat, 14 Mar 2015 02:05:07 +0000 (UTC) Received: from venus.codepro.be (venus.codepro.be [IPv6:2a01:4f8:162:1127::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "*.codepro.be", Issuer "Gandi Standard SSL CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id F0D988B8; Sat, 14 Mar 2015 02:05:05 +0000 (UTC) Received: from vega.codepro.be (unknown [172.16.1.3]) by venus.codepro.be (Postfix) with ESMTP id 6BC7712C20; Sat, 14 Mar 2015 03:05:01 +0100 (CET) Received: by vega.codepro.be (Postfix, from userid 1001) id 631AC2E0A2; Sat, 14 Mar 2015 03:05:01 +0100 (CET) Date: Sat, 14 Mar 2015 03:05:01 +0100 From: Kristof Provost To: freebsd-pf@freebsd.org, freebsd-net@freebsd.org Subject: Re: PF IPv6 fragments handling Message-ID: <20150314020500.GW1975@vega.codepro.be> References: <20150203202519.GD2167@vega.codepro.be> <20150209232416.GB37777@vega.codepro.be> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20150209232416.GB37777@vega.codepro.be> X-PGP-Fingerprint: E114 D9EA 909E D469 8F57 17A5 7D15 91C6 9EFA F286 X-Checked-By-NSA: Probably User-Agent: Mutt/1.5.23 (2014-03-12) Cc: ae@FreeBSD.org, bz@FreeBSD.org X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 14 Mar 2015 02:05:07 -0000 On 2015-02-10 00:24:16 (+0100), Kristof Provost wrote: > On 2015-02-03 21:25:20 (+0100), Kristof Provost wrote: > > Two of my systems are currently running them, seemingly without > > problems. > > > The initial patch set had problems refragmenting in forwarding > scenarios. That should be fixed with the update to > https://reviews.freebsd.org/D1767 and the extra patch in > https://reviews.freebsd.org/D1815 > Status update: all these patches other than D1815 have been committed. There's one crash I know about in forwarding scenarios (and scrub on output). There's a fix which will be committed as soon as it's had a bit more testing. The blocking point is D1815. There's no consensus on it right now, so I'd like to go over the problem and the two possible solutions I see. The problematic scenario is when we're forwarding fragmented IPv6 packets. Right now the fragmented packets are gathered up on the ip6_input() netpfil hook (through pf_test6() -> pf_normalize_ip6() -> pf_reassemble6()). When we've found all of the fragments pf_reassemble6() will create a reassembled fragment and tag it as having been reassembled. pf_test6() then returns the reassembled packet to the IP stack. That passes through ip6_input() and is handed to ip6_forward(). At that point we run into the packet size check, which in ip6_forward() is done before the pfil(PFIL_OUT) hook. That means that we'll send an ICMP6_PACKET_TOO_BIG error rather than forwarding the packet. The proposed fix in D1815 is to simply move the size check after the pfil(PFIL_OUT) hook so pf has the chance to refragment the packet (which it does in pf_test6() -> pf_refragment6() because the packet has the PF_REASSEMBLED tag). That's also what the OpenBSD stack does. In the D1815 review Gleb Smirnoff proposed a different solution. Instead of returning a reassembled packet from pfil(PFIL_IN) in ip6_input() we could change netpfil so we could return multiple packets. That means we'd reassemble and immediately refragment on the input, and then do the same on the output side. I have a preference for the solution in D1815 for two reasons: - it's less work for me. It's a relatively small change in ip6_output() and nothing else. Changing netpfil so it can return multiple packets is a more invasive change and will impact other firewalls too. - it's less work for the kernel when forwarding. Not only do we only reassemble and refragment once, but we also only need to do ip6_forward() processing on a single packet, rather than for each fragment. Thoughts? Regards, Kristof