Date: Sat, 14 Mar 2015 03:05:01 +0100 From: Kristof Provost <kristof@sigsegv.be> To: freebsd-pf@freebsd.org, freebsd-net@freebsd.org Cc: ae@FreeBSD.org, bz@FreeBSD.org Subject: Re: PF IPv6 fragments handling Message-ID: <20150314020500.GW1975@vega.codepro.be> In-Reply-To: <20150209232416.GB37777@vega.codepro.be> References: <20150203202519.GD2167@vega.codepro.be> <20150209232416.GB37777@vega.codepro.be>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2015-02-10 00:24:16 (+0100), Kristof Provost <kristof@sigsegv.be> wrote: > On 2015-02-03 21:25:20 (+0100), Kristof Provost <kristof@sigsegv.be> 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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20150314020500.GW1975>