Skip site navigation (1)Skip section navigation (2)
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>